diff options
author | Stefano Babic <sbabic@denx.de> | 2015-07-17 11:22:56 +0200 |
---|---|---|
committer | Stefano Babic <sbabic@denx.de> | 2015-07-17 11:22:56 +0200 |
commit | f448c5d3200372fa73f340144d013fdecf4e2f1f (patch) | |
tree | b17b66f67a22b553f66bcb22e69d62cb2a5bbe7e | |
parent | 425640256a7c5e9259f7583ee4eca1f3b70f8032 (diff) | |
parent | 605e15db2b54302364a2528d3c6604fbc57be846 (diff) |
Merge branch 'master' of git://git.denx.de/u-boot
133 files changed, 2544 insertions, 1771 deletions
@@ -60,6 +60,14 @@ usage() exit ${ret} } +deprecation() { + echo "** Note: MAKEALL is deprecated - please use buildman instead" + echo "** See tools/buildman/README for details" + echo +} + +deprecation + SHORT_OPTS="ha:c:v:s:b:lmMCnr" LONG_OPTS="help,arch:,cpu:,vendor:,soc:,board:,list,maintainers,mails,check,continue,rebuild-errors" @@ -827,6 +835,8 @@ print_stats() { kill_children fi + deprecation + exit $RC } @@ -1,7 +1,7 @@ VERSION = 2015 PATCHLEVEL = 07 SUBLEVEL = -EXTRAVERSION = -rc3 +EXTRAVERSION = NAME = # *DOCUMENTATION* @@ -565,6 +565,7 @@ KBUILD_CFLAGS += -DBUILD_TAG='"$(BUILD_TAG)"' endif KBUILD_CFLAGS += $(call cc-option,-fno-stack-protector) +KBUILD_CFLAGS += $(call cc-option,-fno-delete-null-pointer-checks) KBUILD_CFLAGS += -g # $(KBUILD_AFLAGS) sets -g, which causes gcc to pass a suitable -g<format> @@ -1034,8 +1035,8 @@ ifneq ($(CONFIG_HAVE_CMC),) IFDTOOL_FLAGS += -w $(CONFIG_CMC_ADDR):$(srctree)/board/$(BOARDDIR)/$(CONFIG_CMC_FILE) endif -ifneq ($(CONFIG_X86_OPTION_ROM_ADDR),) -IFDTOOL_FLAGS += -w $(CONFIG_X86_OPTION_ROM_ADDR):$(srctree)/board/$(BOARDDIR)/$(CONFIG_X86_OPTION_ROM_FILE) +ifneq ($(CONFIG_HAVE_VGA_BIOS),) +IFDTOOL_FLAGS += -w $(CONFIG_VGA_BIOS_ADDR):$(srctree)/board/$(BOARDDIR)/$(CONFIG_VGA_BIOS_FILE) endif quiet_cmd_ifdtool = IFDTOOL $@ diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 9908b430d6..506463c12c 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -227,6 +227,9 @@ config TARGET_STV0991 select CPU_V7 select DM select DM_SERIAL + select DM_SPI + select DM_SPI_FLASH + select SPI_FLASH config TARGET_X600 bool "Support x600" diff --git a/arch/arm/cpu/armv7/stv0991/clock.c b/arch/arm/cpu/armv7/stv0991/clock.c index 70b8a8d984..26c0d3637d 100644 --- a/arch/arm/cpu/armv7/stv0991/clock.c +++ b/arch/arm/cpu/armv7/stv0991/clock.c @@ -33,7 +33,9 @@ void clock_setup(int peripheral) /* Clock selection for ethernet tx_clk & rx_clk*/ writel((readl(&stv0991_cgu_regs->eth_ctrl) & ETH_CLK_MASK) | ETH_CLK_CTRL, &stv0991_cgu_regs->eth_ctrl); - + break; + case QSPI_CLOCK_CFG: + writel(QSPI_CLK_CTRL, &stv0991_cgu_regs->qspi_freq); break; default: break; diff --git a/arch/arm/cpu/armv7/stv0991/pinmux.c b/arch/arm/cpu/armv7/stv0991/pinmux.c index 1d086a235d..24c67faaea 100644 --- a/arch/arm/cpu/armv7/stv0991/pinmux.c +++ b/arch/arm/cpu/armv7/stv0991/pinmux.c @@ -55,6 +55,11 @@ int stv0991_pinmux_config(int peripheral) ETH_M_VDD_CFG, &stv0991_creg->vdd_pad1); break; + case QSPI_CS_CLK_PAD: + writel((readl(&stv0991_creg->mux13) & FLASH_CS_NC_MASK) | + CFG_FLASH_CS_NC, &stv0991_creg->mux13); + writel((readl(&stv0991_creg->mux13) & FLASH_CLK_MASK) | + CFG_FLASH_CLK, &stv0991_creg->mux13); default: break; } diff --git a/arch/arm/dts/socfpga.dtsi b/arch/arm/dts/socfpga.dtsi index bf791c5dde..9b1242025d 100644 --- a/arch/arm/dts/socfpga.dtsi +++ b/arch/arm/dts/socfpga.dtsi @@ -639,6 +639,7 @@ ext-decoder = <0>; /* external decoder */ num-cs = <4>; fifo-depth = <128>; + sram-size = <128>; bus-num = <2>; status = "disabled"; }; diff --git a/arch/arm/dts/stv0991.dts b/arch/arm/dts/stv0991.dts index b25c48bcec..fa3fd641b2 100644 --- a/arch/arm/dts/stv0991.dts +++ b/arch/arm/dts/stv0991.dts @@ -20,4 +20,34 @@ reg = <0x80406000 0x1000>; clock = <2700000>; }; + + aliases { + spi0 = "/spi@80203000"; /* QSPI */ + }; + + qspi: spi@80203000 { + compatible = "cadence,qspi"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x80203000 0x100>, + <0x40000000 0x1000000>; + clocks = <3750000>; + sram-size = <256>; + status = "okay"; + + flash0: n25q32@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "spi-flash"; + reg = <0>; /* chip select */ + spi-max-frequency = <50000000>; + m25p,fast-read; + page-size = <256>; + block-size = <16>; /* 2^16, 64KB */ + tshsl-ns = <50>; + tsd2d-ns = <50>; + tchsh-ns = <4>; + tslch-ns = <4>; + }; + }; }; diff --git a/arch/arm/include/asm/arch-stv0991/stv0991_cgu.h b/arch/arm/include/asm/arch-stv0991/stv0991_cgu.h index ddcbb57a92..f0045f3e04 100644 --- a/arch/arm/include/asm/arch-stv0991/stv0991_cgu.h +++ b/arch/arm/include/asm/arch-stv0991/stv0991_cgu.h @@ -113,4 +113,19 @@ struct stv0991_cgu_regs { #define ETH_CLK_CTRL (ETH_CLK_RX_EXT_PHY << RX_CLK_SHIFT \ | ETH_CLK_TX_EXT_PHY) +/* CGU qspi clock */ +#define DIV_HCLK1_SHIFT 9 +#define DIV_CRYP_SHIFT 6 +#define MDIV_QSPI_SHIFT 3 + +#define CLK_QSPI_OSC 0 +#define CLK_QSPI_MCLK 1 +#define CLK_QSPI_PLL1 2 +#define CLK_QSPI_PLL2 3 + +#define QSPI_CLK_CTRL (3 << DIV_HCLK1_SHIFT \ + | 1 << DIV_CRYP_SHIFT \ + | 0 << MDIV_QSPI_SHIFT \ + | CLK_QSPI_OSC) + #endif diff --git a/arch/arm/include/asm/arch-stv0991/stv0991_creg.h b/arch/arm/include/asm/arch-stv0991/stv0991_creg.h index c804eb5e4c..737c95253b 100644 --- a/arch/arm/include/asm/arch-stv0991/stv0991_creg.h +++ b/arch/arm/include/asm/arch-stv0991/stv0991_creg.h @@ -49,6 +49,15 @@ struct stv0991_creg { u32 vdd_comp1; /* offset 0x400 */ }; +/* CREG MUX 13 register */ +#define FLASH_CS_NC_SHIFT 4 +#define FLASH_CS_NC_MASK ~(7 << FLASH_CS_NC_SHIFT) +#define CFG_FLASH_CS_NC (0 << FLASH_CS_NC_SHIFT) + +#define FLASH_CLK_SHIFT 0 +#define FLASH_CLK_MASK ~(7 << FLASH_CLK_SHIFT) +#define CFG_FLASH_CLK (0 << FLASH_CLK_SHIFT) + /* CREG MUX 12 register */ #define GPIOC_30_MUX_SHIFT 24 #define GPIOC_30_MUX_MASK ~(1 << GPIOC_30_MUX_SHIFT) diff --git a/arch/arm/include/asm/arch-stv0991/stv0991_periph.h b/arch/arm/include/asm/arch-stv0991/stv0991_periph.h index f728c83cb7..725da838b8 100644 --- a/arch/arm/include/asm/arch-stv0991/stv0991_periph.h +++ b/arch/arm/include/asm/arch-stv0991/stv0991_periph.h @@ -18,6 +18,7 @@ enum periph_id { UART_GPIOC_30_31 = 0, UART_GPIOB_16_17, ETH_GPIOB_10_31_C_0_4, + QSPI_CS_CLK_PAD, PERIPH_ID_I2C0, PERIPH_ID_I2C1, PERIPH_ID_I2C2, @@ -39,6 +40,7 @@ enum periph_id { enum periph_clock { UART_CLOCK_CFG = 0, ETH_CLOCK_CFG, + QSPI_CLOCK_CFG, }; #endif /* __ASM_ARM_ARCH_PERIPH_H */ diff --git a/arch/arm/mach-mvebu/cpu.c b/arch/arm/mach-mvebu/cpu.c index 0121db8bb5..9bc9f002d8 100644 --- a/arch/arm/mach-mvebu/cpu.c +++ b/arch/arm/mach-mvebu/cpu.c @@ -6,10 +6,13 @@ #include <common.h> #include <netdev.h> +#include <ahci.h> +#include <linux/mbus.h> #include <asm/io.h> #include <asm/pl310.h> #include <asm/arch/cpu.h> #include <asm/arch/soc.h> +#include <sdhci.h> #define DDR_BASE_CS_OFF(n) (0x0000 + ((n) << 3)) #define DDR_SIZE_CS_OFF(n) (0x0004 + ((n) << 3)) @@ -245,6 +248,69 @@ int cpu_eth_init(bd_t *bis) } #endif +#ifdef CONFIG_MV_SDHCI +int board_mmc_init(bd_t *bis) +{ + mv_sdh_init(MVEBU_SDIO_BASE, 0, 0, + SDHCI_QUIRK_32BIT_DMA_ADDR | SDHCI_QUIRK_WAIT_SEND_CMD); + + return 0; +} +#endif + +#ifdef CONFIG_SCSI_AHCI_PLAT +#define AHCI_VENDOR_SPECIFIC_0_ADDR 0xa0 +#define AHCI_VENDOR_SPECIFIC_0_DATA 0xa4 + +#define AHCI_WINDOW_CTRL(win) (0x60 + ((win) << 4)) +#define AHCI_WINDOW_BASE(win) (0x64 + ((win) << 4)) +#define AHCI_WINDOW_SIZE(win) (0x68 + ((win) << 4)) + +static void ahci_mvebu_mbus_config(void __iomem *base) +{ + const struct mbus_dram_target_info *dram; + int i; + + dram = mvebu_mbus_dram_info(); + + for (i = 0; i < 4; i++) { + writel(0, base + AHCI_WINDOW_CTRL(i)); + writel(0, base + AHCI_WINDOW_BASE(i)); + writel(0, base + AHCI_WINDOW_SIZE(i)); + } + + for (i = 0; i < dram->num_cs; i++) { + const struct mbus_dram_window *cs = dram->cs + i; + + writel((cs->mbus_attr << 8) | + (dram->mbus_dram_target_id << 4) | 1, + base + AHCI_WINDOW_CTRL(i)); + writel(cs->base >> 16, base + AHCI_WINDOW_BASE(i)); + writel(((cs->size - 1) & 0xffff0000), + base + AHCI_WINDOW_SIZE(i)); + } +} + +static void ahci_mvebu_regret_option(void __iomem *base) +{ + /* + * Enable the regret bit to allow the SATA unit to regret a + * request that didn't receive an acknowlegde and avoid a + * deadlock + */ + writel(0x4, base + AHCI_VENDOR_SPECIFIC_0_ADDR); + writel(0x80, base + AHCI_VENDOR_SPECIFIC_0_DATA); +} + +void scsi_init(void) +{ + printf("MVEBU SATA INIT\n"); + ahci_mvebu_mbus_config((void __iomem *)MVEBU_SATA0_BASE); + ahci_mvebu_regret_option((void __iomem *)MVEBU_SATA0_BASE); + ahci_init((void __iomem *)MVEBU_SATA0_BASE); +} +#endif + #ifndef CONFIG_SYS_DCACHE_OFF void enable_caches(void) { diff --git a/arch/arm/mach-mvebu/include/mach/cpu.h b/arch/arm/mach-mvebu/include/mach/cpu.h index 3b48460a0b..4bdb6331e1 100644 --- a/arch/arm/mach-mvebu/include/mach/cpu.h +++ b/arch/arm/mach-mvebu/include/mach/cpu.h @@ -114,6 +114,8 @@ void mvebu_sdram_size_adjust(enum memory_bank bank); int mvebu_mbus_probe(struct mbus_win windows[], int count); int mvebu_soc_family(void); +int mv_sdh_init(unsigned long regbase, u32 max_clk, u32 min_clk, u32 quirks); + /* * Highspeed SERDES PHY config init, ported from bin_hdr * to mainline U-Boot diff --git a/arch/arm/mach-mvebu/include/mach/gpio.h b/arch/arm/mach-mvebu/include/mach/gpio.h new file mode 100644 index 0000000000..09e3c503dd --- /dev/null +++ b/arch/arm/mach-mvebu/include/mach/gpio.h @@ -0,0 +1,10 @@ +/* + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __MACH_MVEBU_GPIO_H +#define __MACH_MVEBU_GPIO_H + +/* Empty file - sdhci requires this. */ + +#endif diff --git a/arch/arm/mach-mvebu/include/mach/soc.h b/arch/arm/mach-mvebu/include/mach/soc.h index 0a9307c8ce..1aaea672ee 100644 --- a/arch/arm/mach-mvebu/include/mach/soc.h +++ b/arch/arm/mach-mvebu/include/mach/soc.h @@ -49,8 +49,11 @@ #define MVEBU_EGIGA2_BASE (MVEBU_REGISTER(0x30000)) #define MVEBU_EGIGA3_BASE (MVEBU_REGISTER(0x34000)) #define MVEBU_REG_PCIE_BASE (MVEBU_REGISTER(0x40000)) +#define MVEBU_USB20_BASE (MVEBU_REGISTER(0x58000)) #define MVEBU_EGIGA0_BASE (MVEBU_REGISTER(0x70000)) #define MVEBU_EGIGA1_BASE (MVEBU_REGISTER(0x74000)) +#define MVEBU_SATA0_BASE (MVEBU_REGISTER(0xa8000)) +#define MVEBU_SDIO_BASE (MVEBU_REGISTER(0xd8000)) #define SDRAM_MAX_CS 4 #define SDRAM_ADDR_MASK 0xFF000000 diff --git a/arch/mips/include/asm/cacheops.h b/arch/mips/include/asm/cacheops.h index 75ec380980..af2adc701e 100644 --- a/arch/mips/include/asm/cacheops.h +++ b/arch/mips/include/asm/cacheops.h @@ -18,7 +18,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, %1" : : "i"(op), "R"(addr)); #endif } diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h index 3fa37f5dd2..a7ab087c0d 100644 --- a/arch/mips/include/asm/io.h +++ b/arch/mips/include/asm/io.h @@ -117,7 +117,7 @@ static inline void set_io_port_base(unsigned long base) * Change virtual addresses to physical addresses and vv. * These are trivial on the 1:1 Linux/MIPS mapping */ -extern inline phys_addr_t virt_to_phys(volatile void * address) +static inline phys_addr_t virt_to_phys(volatile void * address) { #ifndef CONFIG_64BIT return CPHYSADDR(address); @@ -126,7 +126,7 @@ extern inline phys_addr_t virt_to_phys(volatile void * address) #endif } -extern inline void * phys_to_virt(unsigned long address) +static inline void * phys_to_virt(unsigned long address) { #ifndef CONFIG_64BIT return (void *)KSEG0ADDR(address); @@ -138,7 +138,7 @@ extern inline void * phys_to_virt(unsigned long address) /* * IO bus memory addresses are also 1:1 with the physical address */ -extern inline unsigned long virt_to_bus(volatile void * address) +static inline unsigned long virt_to_bus(volatile void * address) { #ifndef CONFIG_64BIT return CPHYSADDR(address); @@ -147,7 +147,7 @@ extern inline unsigned long virt_to_bus(volatile void * address) #endif } -extern inline void * bus_to_virt(unsigned long address) +static inline void * bus_to_virt(unsigned long address) { #ifndef CONFIG_64BIT return (void *)KSEG0ADDR(address); @@ -165,12 +165,12 @@ extern unsigned long isa_slot_offset; extern void * __ioremap(unsigned long offset, unsigned long size, unsigned long flags); #if 0 -extern inline void *ioremap(unsigned long offset, unsigned long size) +static inline void *ioremap(unsigned long offset, unsigned long size) { return __ioremap(offset, size, _CACHE_UNCACHED); } -extern inline void *ioremap_nocache(unsigned long offset, unsigned long size) +static inline void *ioremap_nocache(unsigned long offset, unsigned long size) { return __ioremap(offset, size, _CACHE_UNCACHED); } diff --git a/arch/mips/include/asm/system.h b/arch/mips/include/asm/system.h index 7a2895284e..d56f73b8b8 100644 --- a/arch/mips/include/asm/system.h +++ b/arch/mips/include/asm/system.h @@ -22,7 +22,7 @@ #include <linux/kernel.h> #endif -extern __inline__ void +static __inline__ void __sti(void) { __asm__ __volatile__( @@ -46,7 +46,7 @@ __sti(void) * R4000/R4400 need three nops, the R4600 two nops and the R10000 needs * no nops at all. */ -extern __inline__ void +static __inline__ void __cli(void) { __asm__ __volatile__( @@ -207,7 +207,7 @@ do { \ * For 32 and 64 bit operands we can take advantage of ll and sc. * FIXME: This doesn't work for R3000 machines. */ -extern __inline__ unsigned long xchg_u32(volatile int * m, unsigned long val) +static __inline__ unsigned long xchg_u32(volatile int * m, unsigned long val) { #ifdef CONFIG_CPU_HAS_LLSC unsigned long dummy; diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 20083e68c3..cbbaa4f2ce 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -69,6 +69,21 @@ config X86_RESET_VECTOR bool default n +config RESET_SEG_START + hex + depends on X86_RESET_VECTOR + default 0xffff0000 + +config RESET_SEG_SIZE + hex + depends on X86_RESET_VECTOR + default 0x10000 + +config RESET_VEC_LOC + hex + depends on X86_RESET_VECTOR + default 0xfffffff0 + config SYS_X86_START16 hex depends on X86_RESET_VECTOR @@ -173,14 +188,6 @@ config X86_RAMTEST to work correctly. It is not exhaustive but can save time by detecting obvious failures. -config MARK_GRAPHICS_MEM_WRCOMB - bool "Mark graphics memory as write-combining" - default n - help - The graphics performance may increase if the graphics - memory is set as write-combining cache type. This option - enables marking the graphics memory as write-combining. - config HAVE_FSP bool "Add an Firmware Support Package binary" help @@ -220,17 +227,6 @@ config FSP_TEMP_RAM_ADDR Stack top address which is used in FspInit after DRAM is ready and CAR is disabled. -config MAX_CPUS - int "Maximum number of CPUs permitted" - default 4 - help - When using multi-CPU chips it is possible for U-Boot to start up - more than one CPU. The stack memory used by all of these CPUs is - pre-allocated so at present U-Boot wants to know the maximum - number of CPUs that may be present. Set this to at least as high - as the number of CPUs in your system (it uses about 4KB of RAM for - each CPU). - config SMP bool "Enable Symmetric Multiprocessing" default n @@ -241,8 +237,21 @@ config SMP only one CPU will be enabled regardless of the number of CPUs available. +config MAX_CPUS + int "Maximum number of CPUs permitted" + depends on SMP + default 4 + help + When using multi-CPU chips it is possible for U-Boot to start up + more than one CPU. The stack memory used by all of these CPUs is + pre-allocated so at present U-Boot wants to know the maximum + number of CPUs that may be present. Set this to at least as high + as the number of CPUs in your system (it uses about 4KB of RAM for + each CPU). + config AP_STACK_SIZE hex + depends on SMP default 0x1000 help Each additional CPU started by U-Boot requires its own stack. This @@ -270,6 +279,28 @@ config TSC_FREQ_IN_MHZ help The running frequency in MHz of Time-Stamp Counter (TSC). +config HAVE_VGA_BIOS + bool "Add a VGA BIOS image" + help + Select this option if you have a VGA BIOS image that you would + like to add to your ROM. + +config VGA_BIOS_FILE + string "VGA BIOS image filename" + depends on HAVE_VGA_BIOS + default "vga.bin" + help + The filename of the VGA BIOS image in the board directory. + +config VGA_BIOS_ADDR + hex "VGA BIOS image location" + depends on HAVE_VGA_BIOS + default 0xfff90000 + help + The location of VGA BIOS image in the SPI flash. For example, base + address of 0xfff90000 indicates that the image will be put at offset + 0x90000 from the beginning of a 1MB flash device. + menu "System tables" config GENERATE_PIRQ_TABLE @@ -296,6 +327,15 @@ config GENERATE_SFI_TABLE For more information, see http://simplefirmware.org +config GENERATE_MP_TABLE + bool "Generate an MP (Multi-Processor) table" + default n + help + Generate an MP (Multi-Processor) table for this board. The MP table + provides a way for the operating system to support for symmetric + multiprocessing as well as symmetric I/O interrupt handling with + the local APIC and I/O APIC. + endmenu config MAX_PIRQ_LINKS diff --git a/arch/x86/cpu/Makefile b/arch/x86/cpu/Makefile index 7ff05e6628..8a8e63e1d3 100644 --- a/arch/x86/cpu/Makefile +++ b/arch/x86/cpu/Makefile @@ -10,7 +10,7 @@ extra-y = start.o obj-$(CONFIG_X86_RESET_VECTOR) += resetvec.o start16.o -obj-y += interrupts.o cpu.o call64.o +obj-y += interrupts.o cpu.o cpu_x86.o call64.o obj-$(CONFIG_INTEL_BAYTRAIL) += baytrail/ obj-$(CONFIG_SYS_COREBOOT) += coreboot/ @@ -19,7 +19,7 @@ obj-$(CONFIG_NORTHBRIDGE_INTEL_SANDYBRIDGE) += ivybridge/ obj-$(CONFIG_NORTHBRIDGE_INTEL_IVYBRIDGE) += ivybridge/ obj-$(CONFIG_INTEL_QUARK) += quark/ obj-$(CONFIG_INTEL_QUEENSBAY) += queensbay/ -obj-y += irq.o lapic.o +obj-y += irq.o lapic.o ioapic.o obj-$(CONFIG_SMP) += mp_init.o obj-y += mtrr.o obj-$(CONFIG_PCI) += pci.o diff --git a/arch/x86/cpu/baytrail/Makefile b/arch/x86/cpu/baytrail/Makefile index c78b644eb7..5be5491643 100644 --- a/arch/x86/cpu/baytrail/Makefile +++ b/arch/x86/cpu/baytrail/Makefile @@ -7,5 +7,4 @@ obj-y += cpu.o obj-y += early_uart.o obj-y += fsp_configs.o -obj-y += pci.o obj-y += valleyview.o diff --git a/arch/x86/cpu/baytrail/cpu.c b/arch/x86/cpu/baytrail/cpu.c index 1d482064b2..a0117308ae 100644 --- a/arch/x86/cpu/baytrail/cpu.c +++ b/arch/x86/cpu/baytrail/cpu.c @@ -10,79 +10,11 @@ #include <cpu.h> #include <dm.h> #include <asm/cpu.h> +#include <asm/cpu_x86.h> #include <asm/lapic.h> -#include <asm/mp.h> #include <asm/msr.h> #include <asm/turbo.h> -#ifdef CONFIG_SMP -static int enable_smis(struct udevice *cpu, void *unused) -{ - return 0; -} - -static struct mp_flight_record mp_steps[] = { - MP_FR_BLOCK_APS(mp_init_cpu, NULL, mp_init_cpu, NULL), - /* Wait for APs to finish initialization before proceeding. */ - MP_FR_BLOCK_APS(NULL, NULL, enable_smis, NULL), -}; - -static int detect_num_cpus(void) -{ - int ecx = 0; - - /* - * Use the algorithm described in Intel 64 and IA-32 Architectures - * Software Developer's Manual Volume 3 (3A, 3B & 3C): System - * Programming Guide, Jan-2015. Section 8.9.2: Hierarchical Mapping - * of CPUID Extended Topology Leaf. - */ - while (1) { - struct cpuid_result leaf_b; - - leaf_b = cpuid_ext(0xb, ecx); - - /* - * Bay Trail doesn't have hyperthreading so just determine the - * number of cores by from level type (ecx[15:8] == * 2) - */ - if ((leaf_b.ecx & 0xff00) == 0x0200) - return leaf_b.ebx & 0xffff; - ecx++; - } -} - -static int baytrail_init_cpus(void) -{ - struct mp_params mp_params; - - lapic_setup(); - - mp_params.num_cpus = detect_num_cpus(); - mp_params.parallel_microcode_load = 0, - mp_params.flight_plan = &mp_steps[0]; - mp_params.num_records = ARRAY_SIZE(mp_steps); - mp_params.microcode_pointer = 0; - - if (mp_init(&mp_params)) { - printf("Warning: MP init failure\n"); - return -EIO; - } - - return 0; -} -#endif - -int x86_init_cpus(void) -{ -#ifdef CONFIG_SMP - debug("Init additional CPUs\n"); - baytrail_init_cpus(); -#endif - - return 0; -} - static void set_max_freq(void) { msr_t perf_ctl; @@ -175,19 +107,38 @@ static int baytrail_get_info(struct udevice *dev, struct cpu_info *info) return 0; } -static int cpu_x86_baytrail_bind(struct udevice *dev) +static int baytrail_get_count(struct udevice *dev) { - struct cpu_platdata *plat = dev_get_parent_platdata(dev); + int ecx = 0; + + /* + * Use the algorithm described in Intel 64 and IA-32 Architectures + * Software Developer's Manual Volume 3 (3A, 3B & 3C): System + * Programming Guide, Jan-2015. Section 8.9.2: Hierarchical Mapping + * of CPUID Extended Topology Leaf. + */ + while (1) { + struct cpuid_result leaf_b; + + leaf_b = cpuid_ext(0xb, ecx); + + /* + * Bay Trail doesn't have hyperthreading so just determine the + * number of cores by from level type (ecx[15:8] == * 2) + */ + if ((leaf_b.ecx & 0xff00) == 0x0200) + return leaf_b.ebx & 0xffff; - plat->cpu_id = fdtdec_get_int(gd->fdt_blob, dev->of_offset, - "intel,apic-id", -1); + ecx++; + } return 0; } static const struct cpu_ops cpu_x86_baytrail_ops = { - .get_desc = x86_cpu_get_desc, + .get_desc = cpu_x86_get_desc, .get_info = baytrail_get_info, + .get_count = baytrail_get_count, }; static const struct udevice_id cpu_x86_baytrail_ids[] = { @@ -199,7 +150,7 @@ U_BOOT_DRIVER(cpu_x86_baytrail_drv) = { .name = "cpu_x86_baytrail", .id = UCLASS_CPU, .of_match = cpu_x86_baytrail_ids, - .bind = cpu_x86_baytrail_bind, + .bind = cpu_x86_bind, .probe = cpu_x86_baytrail_probe, .ops = &cpu_x86_baytrail_ops, }; diff --git a/arch/x86/cpu/baytrail/pci.c b/arch/x86/cpu/baytrail/pci.c deleted file mode 100644 index 48409de5c4..0000000000 --- a/arch/x86/cpu/baytrail/pci.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <pci.h> -#include <asm/pci.h> -#include <asm/fsp/fsp_support.h> - -DECLARE_GLOBAL_DATA_PTR; - -void board_pci_setup_hose(struct pci_controller *hose) -{ - hose->first_busno = 0; - hose->last_busno = 0; - - /* PCI memory space */ - pci_set_region(hose->regions + 0, - CONFIG_PCI_MEM_BUS, - CONFIG_PCI_MEM_PHYS, - CONFIG_PCI_MEM_SIZE, - PCI_REGION_MEM); - - /* PCI IO space */ - pci_set_region(hose->regions + 1, - CONFIG_PCI_IO_BUS, - CONFIG_PCI_IO_PHYS, - CONFIG_PCI_IO_SIZE, - PCI_REGION_IO); - - pci_set_region(hose->regions + 2, - CONFIG_PCI_PREF_BUS, - CONFIG_PCI_PREF_PHYS, - CONFIG_PCI_PREF_SIZE, - PCI_REGION_PREFETCH); - - pci_set_region(hose->regions + 3, - 0, - 0, - gd->ram_size < 0x80000000 ? gd->ram_size : 0x80000000, - PCI_REGION_MEM | PCI_REGION_SYS_MEMORY); - - hose->region_count = 4; -} diff --git a/arch/x86/cpu/config.mk b/arch/x86/cpu/config.mk index 4c4d0c7cd2..1263221e69 100644 --- a/arch/x86/cpu/config.mk +++ b/arch/x86/cpu/config.mk @@ -10,8 +10,8 @@ CROSS_COMPILE ?= i386-linux- PLATFORM_CPPFLAGS += -D__I386__ # DO NOT MODIFY THE FOLLOWING UNLESS YOU REALLY KNOW WHAT YOU ARE DOING! -LDPPFLAGS += -DRESET_SEG_START=0xffff0000 -LDPPFLAGS += -DRESET_SEG_SIZE=0x10000 -LDPPFLAGS += -DRESET_VEC_LOC=0xfffffff0 +LDPPFLAGS += -DRESET_SEG_START=$(CONFIG_RESET_SEG_START) +LDPPFLAGS += -DRESET_SEG_SIZE=$(CONFIG_RESET_SEG_SIZE) +LDPPFLAGS += -DRESET_VEC_LOC=$(CONFIG_RESET_VEC_LOC) LDPPFLAGS += -DSTART_16=$(CONFIG_SYS_X86_START16) LDPPFLAGS += -DRESET_BASE="CONFIG_SYS_TEXT_BASE + (CONFIG_SYS_MONITOR_LEN - RESET_SEG_SIZE)" diff --git a/arch/x86/cpu/coreboot/pci.c b/arch/x86/cpu/coreboot/pci.c index 67eb14ce99..41e29a6086 100644 --- a/arch/x86/cpu/coreboot/pci.c +++ b/arch/x86/cpu/coreboot/pci.c @@ -11,29 +11,7 @@ #include <common.h> #include <dm.h> -#include <errno.h> #include <pci.h> -#include <asm/io.h> -#include <asm/pci.h> - -DECLARE_GLOBAL_DATA_PTR; - -static const struct dm_pci_ops pci_x86_ops = { - .read_config = pci_x86_read_config, - .write_config = pci_x86_write_config, -}; - -static const struct udevice_id pci_x86_ids[] = { - { .compatible = "pci-x86" }, - { } -}; - -U_BOOT_DRIVER(pci_x86_drv) = { - .name = "pci_x86", - .id = UCLASS_PCI, - .of_match = pci_x86_ids, - .ops = &pci_x86_ops, -}; static const struct udevice_id generic_pch_ids[] = { { .compatible = "intel,pch" }, diff --git a/arch/x86/cpu/cpu.c b/arch/x86/cpu/cpu.c index bb4a110c00..af927b94e0 100644 --- a/arch/x86/cpu/cpu.c +++ b/arch/x86/cpu/cpu.c @@ -21,12 +21,15 @@ #include <common.h> #include <command.h> -#include <cpu.h> #include <dm.h> #include <errno.h> #include <malloc.h> #include <asm/control_regs.h> #include <asm/cpu.h> +#include <asm/lapic.h> +#include <asm/mp.h> +#include <asm/msr.h> +#include <asm/mtrr.h> #include <asm/post.h> #include <asm/processor.h> #include <asm/processor-flags.h> @@ -164,6 +167,26 @@ void setup_gdt(gd_t *id, u64 *gdt_addr) load_fs(X86_GDT_ENTRY_32BIT_FS); } +#ifdef CONFIG_HAVE_FSP +/* + * Setup FSP execution environment GDT + * + * Per Intel FSP external architecture specification, before calling any FSP + * APIs, we need make sure the system is in flat 32-bit mode and both the code + * and data selectors should have full 4GB access range. Here we reuse the one + * we used in arch/x86/cpu/start16.S, and reload the segement registers. + */ +void setup_fsp_gdt(void) +{ + load_gdt((const u64 *)(gdt_rom + CONFIG_RESET_SEG_START), 4); + load_ds(X86_GDT_ENTRY_32BIT_DS); + load_ss(X86_GDT_ENTRY_32BIT_DS); + load_es(X86_GDT_ENTRY_32BIT_DS); + load_fs(X86_GDT_ENTRY_32BIT_DS); + load_gs(X86_GDT_ENTRY_32BIT_DS); +} +#endif + int __weak x86_cleanup_before_linux(void) { #ifdef CONFIG_BOOTSTAGE_STASH @@ -330,6 +353,28 @@ int x86_cpu_init_f(void) gd->arch.has_mtrr = has_mtrr(); } + /* Don't allow PCI region 3 to use memory in the 2-4GB memory hole */ + gd->pci_ram_top = 0x80000000U; + + /* Configure fixed range MTRRs for some legacy regions */ + if (gd->arch.has_mtrr) { + u64 mtrr_cap; + + mtrr_cap = native_read_msr(MTRR_CAP_MSR); + if (mtrr_cap & MTRR_CAP_FIX) { + /* Mark the VGA RAM area as uncacheable */ + native_write_msr(MTRR_FIX_16K_A0000_MSR, 0, 0); + + /* Mark the PCI ROM area as uncacheable */ + native_write_msr(MTRR_FIX_4K_C0000_MSR, 0, 0); + native_write_msr(MTRR_FIX_4K_C8000_MSR, 0, 0); + native_write_msr(MTRR_FIX_4K_D0000_MSR, 0, 0); + native_write_msr(MTRR_FIX_4K_D8000_MSR, 0, 0); + + /* Enable the fixed range MTRRs */ + msr_setbits_64(MTRR_DEF_TYPE_MSR, MTRR_DEF_TYPE_FIX_EN); + } + } return 0; } @@ -520,16 +565,6 @@ char *cpu_get_name(char *name) return ptr; } -int x86_cpu_get_desc(struct udevice *dev, char *buf, int size) -{ - if (size < CPU_MAX_NAME_LEN) - return -ENOSPC; - - cpu_get_name(buf); - - return 0; -} - int default_print_cpuinfo(void) { printf("CPU: %s, vendor %s, device %xh\n", @@ -613,28 +648,47 @@ int last_stage_init(void) } #endif -__weak int x86_init_cpus(void) +#ifdef CONFIG_SMP +static int enable_smis(struct udevice *cpu, void *unused) { return 0; } -int cpu_init_r(void) +static struct mp_flight_record mp_steps[] = { + MP_FR_BLOCK_APS(mp_init_cpu, NULL, mp_init_cpu, NULL), + /* Wait for APs to finish initialization before proceeding */ + MP_FR_BLOCK_APS(NULL, NULL, enable_smis, NULL), +}; + +static int x86_mp_init(void) { - return x86_init_cpus(); + struct mp_params mp_params; + + mp_params.parallel_microcode_load = 0, + mp_params.flight_plan = &mp_steps[0]; + mp_params.num_records = ARRAY_SIZE(mp_steps); + mp_params.microcode_pointer = 0; + + if (mp_init(&mp_params)) { + printf("Warning: MP init failure\n"); + return -EIO; + } + + return 0; } +#endif -static const struct cpu_ops cpu_x86_ops = { - .get_desc = x86_cpu_get_desc, -}; +__weak int x86_init_cpus(void) +{ +#ifdef CONFIG_SMP + debug("Init additional CPUs\n"); + x86_mp_init(); +#endif -static const struct udevice_id cpu_x86_ids[] = { - { .compatible = "cpu-x86" }, - { } -}; + return 0; +} -U_BOOT_DRIVER(cpu_x86_drv) = { - .name = "cpu_x86", - .id = UCLASS_CPU, - .of_match = cpu_x86_ids, - .ops = &cpu_x86_ops, -}; +int cpu_init_r(void) +{ + return x86_init_cpus(); +} diff --git a/arch/x86/cpu/cpu_x86.c b/arch/x86/cpu/cpu_x86.c new file mode 100644 index 0000000000..09410416a1 --- /dev/null +++ b/arch/x86/cpu/cpu_x86.c @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <cpu.h> +#include <dm.h> +#include <errno.h> +#include <asm/cpu.h> + +DECLARE_GLOBAL_DATA_PTR; + +int cpu_x86_bind(struct udevice *dev) +{ + struct cpu_platdata *plat = dev_get_parent_platdata(dev); + + plat->cpu_id = fdtdec_get_int(gd->fdt_blob, dev->of_offset, + "intel,apic-id", -1); + + return 0; +} + +int cpu_x86_get_desc(struct udevice *dev, char *buf, int size) +{ + if (size < CPU_MAX_NAME_LEN) + return -ENOSPC; + + cpu_get_name(buf); + + return 0; +} + +static int cpu_x86_get_count(struct udevice *dev) +{ + int node, cpu; + int num = 0; + + node = fdt_path_offset(gd->fdt_blob, "/cpus"); + if (node < 0) + return -ENOENT; + + for (cpu = fdt_first_subnode(gd->fdt_blob, node); + cpu >= 0; + cpu = fdt_next_subnode(gd->fdt_blob, cpu)) { + const char *device_type; + + device_type = fdt_getprop(gd->fdt_blob, cpu, + "device_type", NULL); + if (!device_type) + continue; + if (strcmp(device_type, "cpu") == 0) + num++; + } + + return num; +} + +static const struct cpu_ops cpu_x86_ops = { + .get_desc = cpu_x86_get_desc, + .get_count = cpu_x86_get_count, +}; + +static const struct udevice_id cpu_x86_ids[] = { + { .compatible = "cpu-x86" }, + { } +}; + +U_BOOT_DRIVER(cpu_x86_drv) = { + .name = "cpu_x86", + .id = UCLASS_CPU, + .of_match = cpu_x86_ids, + .bind = cpu_x86_bind, + .ops = &cpu_x86_ops, +}; diff --git a/arch/x86/cpu/ioapic.c b/arch/x86/cpu/ioapic.c new file mode 100644 index 0000000000..112a9c63b4 --- /dev/null +++ b/arch/x86/cpu/ioapic.c @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/ioapic.h> + +u32 io_apic_read(u32 reg) +{ + writel(reg, IO_APIC_INDEX); + return readl(IO_APIC_DATA); +} + +void io_apic_write(u32 reg, u32 val) +{ + writel(reg, IO_APIC_INDEX); + writel(val, IO_APIC_DATA); +} diff --git a/arch/x86/cpu/irq.c b/arch/x86/cpu/irq.c index 74b89ad2ff..97dd000039 100644 --- a/arch/x86/cpu/irq.c +++ b/arch/x86/cpu/irq.c @@ -58,17 +58,28 @@ void pirq_assign_irq(int link, u8 irq) writeb(irq, irq_router.ibase + LINK_N2V(link, base)); } -static inline void fill_irq_info(struct irq_info **slotp, int *entries, u8 bus, - u8 device, u8 func, u8 pin, u8 pirq) +static struct irq_info *check_dup_entry(struct irq_info *slot_base, + int entry_num, int bus, int device) { - struct irq_info *slot = *slotp; + struct irq_info *slot = slot_base; + int i; + + for (i = 0; i < entry_num; i++) { + if (slot->bus == bus && slot->devfn == (device << 3)) + break; + slot++; + } + return (i == entry_num) ? NULL : slot; +} + +static inline void fill_irq_info(struct irq_info *slot, int bus, int device, + int pin, int pirq) +{ slot->bus = bus; - slot->devfn = (device << 3) | func; + slot->devfn = (device << 3) | 0; slot->irq[pin - 1].link = LINK_N2V(pirq, irq_router.link_base); slot->irq[pin - 1].bitmap = irq_router.irq_mask; - (*entries)++; - (*slotp)++; } __weak void cpu_irq_init(void) @@ -84,7 +95,7 @@ static int create_pirq_routing_table(void) int len, count; const u32 *cell; struct irq_routing_table *rt; - struct irq_info *slot; + struct irq_info *slot, *slot_base; int irq_entries = 0; int i; int ret; @@ -161,13 +172,13 @@ static int create_pirq_routing_table(void) /* Populate the PIRQ table fields */ rt->signature = PIRQ_SIGNATURE; rt->version = PIRQ_VERSION; - rt->rtr_bus = 0; + rt->rtr_bus = PCI_BUS(irq_router.bdf); rt->rtr_devfn = (PCI_DEV(irq_router.bdf) << 3) | PCI_FUNC(irq_router.bdf); rt->rtr_vendor = PCI_VENDOR_ID_INTEL; rt->rtr_device = PCI_DEVICE_ID_INTEL_ICH7_31; - slot = rt->slots; + slot_base = rt->slots; /* Now fill in the irq_info entries in the PIRQ table */ for (i = 0; i < count; i++) { @@ -181,9 +192,44 @@ static int create_pirq_routing_table(void) i, PCI_BUS(pr.bdf), PCI_DEV(pr.bdf), PCI_FUNC(pr.bdf), 'A' + pr.pin - 1, 'A' + pr.pirq); - fill_irq_info(&slot, &irq_entries, PCI_BUS(pr.bdf), - PCI_DEV(pr.bdf), PCI_FUNC(pr.bdf), + + slot = check_dup_entry(slot_base, irq_entries, + PCI_BUS(pr.bdf), PCI_DEV(pr.bdf)); + if (slot) { + debug("found entry for bus %d device %d, ", + PCI_BUS(pr.bdf), PCI_DEV(pr.bdf)); + + if (slot->irq[pr.pin - 1].link) { + debug("skipping\n"); + + /* + * Sanity test on the routed PIRQ pin + * + * If they don't match, show a warning to tell + * there might be something wrong with the PIRQ + * routing information in the device tree. + */ + if (slot->irq[pr.pin - 1].link != + LINK_N2V(pr.pirq, irq_router.link_base)) + debug("WARNING: Inconsistent PIRQ routing information\n"); + + cell += sizeof(struct pirq_routing) / + sizeof(u32); + continue; + } else { + debug("writing INT%c\n", 'A' + pr.pin - 1); + fill_irq_info(slot, PCI_BUS(pr.bdf), + PCI_DEV(pr.bdf), pr.pin, pr.pirq); + cell += sizeof(struct pirq_routing) / + sizeof(u32); + continue; + } + } + + slot = slot_base + irq_entries; + fill_irq_info(slot, PCI_BUS(pr.bdf), PCI_DEV(pr.bdf), pr.pin, pr.pirq); + irq_entries++; cell += sizeof(struct pirq_routing) / sizeof(u32); } diff --git a/arch/x86/cpu/ivybridge/Kconfig b/arch/x86/cpu/ivybridge/Kconfig index e4595be3ae..0e249a40a6 100644 --- a/arch/x86/cpu/ivybridge/Kconfig +++ b/arch/x86/cpu/ivybridge/Kconfig @@ -95,7 +95,6 @@ config CPU_SPECIFIC_OPTIONS select ARCH_BOOTBLOCK_X86_32 select ARCH_ROMSTAGE_X86_32 select ARCH_RAMSTAGE_X86_32 - select SMP select SSE2 select UDELAY_LAPIC select CPU_MICROCODE_IN_CBFS diff --git a/arch/x86/cpu/ivybridge/model_206ax.c b/arch/x86/cpu/ivybridge/model_206ax.c index 8b08c40bcb..fd7db97cbd 100644 --- a/arch/x86/cpu/ivybridge/model_206ax.c +++ b/arch/x86/cpu/ivybridge/model_206ax.c @@ -13,12 +13,12 @@ #include <asm/acpi.h> #include <asm/cpu.h> #include <asm/lapic.h> -#include <asm/lapic_def.h> #include <asm/msr.h> #include <asm/mtrr.h> #include <asm/processor.h> #include <asm/speedstep.h> #include <asm/turbo.h> +#include <asm/arch/bd82x6x.h> #include <asm/arch/model_206ax.h> static void enable_vmx(void) diff --git a/arch/x86/cpu/lapic.c b/arch/x86/cpu/lapic.c index 4690603c75..30d23130eb 100644 --- a/arch/x86/cpu/lapic.c +++ b/arch/x86/cpu/lapic.c @@ -8,50 +8,153 @@ */ #include <common.h> -#include <asm/msr.h> #include <asm/io.h> #include <asm/lapic.h> +#include <asm/msr.h> +#include <asm/msr-index.h> #include <asm/post.h> +unsigned long lapic_read(unsigned long reg) +{ + return readl(LAPIC_DEFAULT_BASE + reg); +} + +#define xchg(ptr, v) ((__typeof__(*(ptr)))__xchg((unsigned long)(v), (ptr), \ + sizeof(*(ptr)))) + +struct __xchg_dummy { unsigned long a[100]; }; +#define __xg(x) ((struct __xchg_dummy *)(x)) + +/* + * Note: no "lock" prefix even on SMP. xchg always implies lock anyway. + * + * Note 2: xchg has side effect, so that attribute volatile is necessary, + * but generally the primitive is invalid, *ptr is output argument. + */ +static inline unsigned long __xchg(unsigned long x, volatile void *ptr, + int size) +{ + switch (size) { + case 1: + __asm__ __volatile__("xchgb %b0,%1" + : "=q" (x) + : "m" (*__xg(ptr)), "0" (x) + : "memory"); + break; + case 2: + __asm__ __volatile__("xchgw %w0,%1" + : "=r" (x) + : "m" (*__xg(ptr)), "0" (x) + : "memory"); + break; + case 4: + __asm__ __volatile__("xchgl %0,%1" + : "=r" (x) + : "m" (*__xg(ptr)), "0" (x) + : "memory"); + break; + } + + return x; +} + +void lapic_write(unsigned long reg, unsigned long v) +{ + (void)xchg((volatile unsigned long *)(LAPIC_DEFAULT_BASE + reg), v); +} + +void enable_lapic(void) +{ + msr_t msr; + + msr = msr_read(MSR_IA32_APICBASE); + msr.hi &= 0xffffff00; + msr.lo |= MSR_IA32_APICBASE_ENABLE; + msr.lo &= ~MSR_IA32_APICBASE_BASE; + msr.lo |= LAPIC_DEFAULT_BASE; + msr_write(MSR_IA32_APICBASE, msr); +} + +void disable_lapic(void) +{ + msr_t msr; + + msr = msr_read(MSR_IA32_APICBASE); + msr.lo &= ~MSR_IA32_APICBASE_ENABLE; + msr_write(MSR_IA32_APICBASE, msr); +} + +unsigned long lapicid(void) +{ + return lapic_read(LAPIC_ID) >> 24; +} + +static void lapic_wait_icr_idle(void) +{ + do { } while (lapic_read(LAPIC_ICR) & LAPIC_ICR_BUSY); +} + +int lapic_remote_read(int apicid, int reg, unsigned long *pvalue) +{ + int timeout; + unsigned long status; + int result; + + lapic_wait_icr_idle(); + lapic_write(LAPIC_ICR2, SET_LAPIC_DEST_FIELD(apicid)); + lapic_write(LAPIC_ICR, LAPIC_DM_REMRD | (reg >> 4)); + + timeout = 0; + do { + status = lapic_read(LAPIC_ICR) & LAPIC_ICR_RR_MASK; + } while (status == LAPIC_ICR_RR_INPROG && timeout++ < 1000); + + result = -1; + if (status == LAPIC_ICR_RR_VALID) { + *pvalue = lapic_read(LAPIC_RRR); + result = 0; + } + + return result; +} + void lapic_setup(void) { -#if NEED_LAPIC == 1 +#ifdef CONFIG_SMP /* Only Pentium Pro and later have those MSR stuff */ debug("Setting up local apic: "); /* Enable the local apic */ enable_lapic(); - /* - * Set Task Priority to 'accept all'. - */ - lapic_write_around(LAPIC_TASKPRI, - lapic_read_around(LAPIC_TASKPRI) & ~LAPIC_TPRI_MASK); + /* Set Task Priority to 'accept all' */ + lapic_write(LAPIC_TASKPRI, + lapic_read(LAPIC_TASKPRI) & ~LAPIC_TPRI_MASK); /* Put the local apic in virtual wire mode */ - lapic_write_around(LAPIC_SPIV, (lapic_read_around(LAPIC_SPIV) & - ~(LAPIC_VECTOR_MASK)) | LAPIC_SPIV_ENABLE); - lapic_write_around(LAPIC_LVT0, (lapic_read_around(LAPIC_LVT0) & - ~(LAPIC_LVT_MASKED | LAPIC_LVT_LEVEL_TRIGGER | - LAPIC_LVT_REMOTE_IRR | LAPIC_INPUT_POLARITY | - LAPIC_SEND_PENDING | LAPIC_LVT_RESERVED_1 | - LAPIC_DELIVERY_MODE_MASK)) | - (LAPIC_LVT_REMOTE_IRR | LAPIC_SEND_PENDING | - LAPIC_DELIVERY_MODE_EXTINT)); - lapic_write_around(LAPIC_LVT1, (lapic_read_around(LAPIC_LVT1) & - ~(LAPIC_LVT_MASKED | LAPIC_LVT_LEVEL_TRIGGER | - LAPIC_LVT_REMOTE_IRR | LAPIC_INPUT_POLARITY | - LAPIC_SEND_PENDING | LAPIC_LVT_RESERVED_1 | - LAPIC_DELIVERY_MODE_MASK)) | - (LAPIC_LVT_REMOTE_IRR | LAPIC_SEND_PENDING | - LAPIC_DELIVERY_MODE_NMI)); + lapic_write(LAPIC_SPIV, (lapic_read(LAPIC_SPIV) & + ~(LAPIC_VECTOR_MASK)) | LAPIC_SPIV_ENABLE); + lapic_write(LAPIC_LVT0, (lapic_read(LAPIC_LVT0) & + ~(LAPIC_LVT_MASKED | LAPIC_LVT_LEVEL_TRIGGER | + LAPIC_LVT_REMOTE_IRR | LAPIC_INPUT_POLARITY | + LAPIC_SEND_PENDING | LAPIC_LVT_RESERVED_1 | + LAPIC_DELIVERY_MODE_MASK)) | + (LAPIC_LVT_REMOTE_IRR | LAPIC_SEND_PENDING | + LAPIC_DELIVERY_MODE_EXTINT)); + lapic_write(LAPIC_LVT1, (lapic_read(LAPIC_LVT1) & + ~(LAPIC_LVT_MASKED | LAPIC_LVT_LEVEL_TRIGGER | + LAPIC_LVT_REMOTE_IRR | LAPIC_INPUT_POLARITY | + LAPIC_SEND_PENDING | LAPIC_LVT_RESERVED_1 | + LAPIC_DELIVERY_MODE_MASK)) | + (LAPIC_LVT_REMOTE_IRR | LAPIC_SEND_PENDING | + LAPIC_DELIVERY_MODE_NMI)); debug("apic_id: 0x%02lx, ", lapicid()); -#else /* !NEED_LLAPIC */ +#else /* !CONFIG_SMP */ /* Only Pentium Pro and later have those MSR stuff */ debug("Disabling local apic: "); disable_lapic(); -#endif /* !NEED_LAPIC */ +#endif /* CONFIG_SMP */ debug("done.\n"); post_code(POST_LAPIC); } diff --git a/arch/x86/cpu/mp_init.c b/arch/x86/cpu/mp_init.c index ac5753a1fd..e686b28c9c 100644 --- a/arch/x86/cpu/mp_init.c +++ b/arch/x86/cpu/mp_init.c @@ -16,12 +16,17 @@ #include <asm/interrupt.h> #include <asm/lapic.h> #include <asm/mp.h> +#include <asm/msr.h> #include <asm/mtrr.h> +#include <asm/processor.h> #include <asm/sipi.h> #include <dm/device-internal.h> #include <dm/uclass-internal.h> #include <linux/linkage.h> +/* Total CPUs include BSP */ +static int num_cpus; + /* This also needs to match the sipi.S assembly code for saved MSR encoding */ struct saved_msr { uint32_t index; @@ -56,6 +61,13 @@ static inline void release_barrier(atomic_t *b) atomic_set(b, 1); } +static inline void stop_this_cpu(void) +{ + /* Called by an AP when it is ready to halt and wait for a new task */ + for (;;) + cpu_hlt(); +} + /* Returns 1 if timeout waiting for APs. 0 if target APs found */ static int wait_for_aps(atomic_t *val, int target, int total_delay, int delay_step) @@ -314,9 +326,9 @@ static int start_aps(int ap_count, atomic_t *num_aps) } /* Send INIT IPI to all but self */ - lapic_write_around(LAPIC_ICR2, SET_LAPIC_DEST_FIELD(0)); - lapic_write_around(LAPIC_ICR, LAPIC_DEST_ALLBUT | LAPIC_INT_ASSERT | - LAPIC_DM_INIT); + 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"); mdelay(10); @@ -331,9 +343,9 @@ static int start_aps(int ap_count, atomic_t *num_aps) } } - lapic_write_around(LAPIC_ICR2, SET_LAPIC_DEST_FIELD(0)); - lapic_write_around(LAPIC_ICR, LAPIC_DEST_ALLBUT | LAPIC_INT_ASSERT | - LAPIC_DM_STARTUP | sipi_vector); + 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"); @@ -356,9 +368,9 @@ static int start_aps(int ap_count, atomic_t *num_aps) } } - lapic_write_around(LAPIC_ICR2, SET_LAPIC_DEST_FIELD(0)); - lapic_write_around(LAPIC_ICR, LAPIC_DEST_ALLBUT | LAPIC_INT_ASSERT | - LAPIC_DM_STARTUP | sipi_vector); + 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"); @@ -383,7 +395,7 @@ static int bsp_do_flight_plan(struct udevice *cpu, struct mp_params *mp_params) int ret = 0; const int timeout_us = 100000; const int step_us = 100; - int num_aps = mp_params->num_cpus - 1; + int num_aps = num_cpus - 1; for (i = 0; i < mp_params->num_records; i++) { struct mp_flight_record *rec = &mp_params->flight_plan[i]; @@ -415,7 +427,7 @@ static int init_bsp(struct udevice **devp) cpu_get_name(processor_name); debug("CPU: %s.\n", processor_name); - enable_lapic(); + lapic_setup(); apic_id = lapicid(); ret = find_cpu_by_apid_id(apic_id, devp); @@ -451,7 +463,16 @@ int mp_init(struct mp_params *p) return -1; } - ret = check_cpu_devices(p->num_cpus); + num_cpus = cpu_get_count(cpu); + if (num_cpus < 0) { + debug("Cannot get number of CPUs: err=%d\n", num_cpus); + return num_cpus; + } + + if (num_cpus < 2) + debug("Warning: Only 1 CPU is detected\n"); + + ret = check_cpu_devices(num_cpus); if (ret) debug("Warning: Device tree does not describe all CPUs. Extra ones will not be started correctly\n"); @@ -471,7 +492,7 @@ int mp_init(struct mp_params *p) wbinvd(); /* Start the APs providing number of APs and the cpus_entered field */ - num_aps = p->num_cpus - 1; + num_aps = num_cpus - 1; ret = start_aps(num_aps, ap_count); if (ret) { mdelay(1000); diff --git a/arch/x86/cpu/queensbay/Kconfig b/arch/x86/cpu/queensbay/Kconfig index 397e599f93..fbf85f233f 100644 --- a/arch/x86/cpu/queensbay/Kconfig +++ b/arch/x86/cpu/queensbay/Kconfig @@ -38,4 +38,8 @@ config CMC_ADDR The default base address of 0xfffb0000 indicates that the binary must be located at offset 0xb0000 from the beginning of a 1MB flash device. +config CPU_ADDR_BITS + int + default 32 + endif diff --git a/arch/x86/cpu/queensbay/tnc.c b/arch/x86/cpu/queensbay/tnc.c index 873de7be9d..d27b2d9ec6 100644 --- a/arch/x86/cpu/queensbay/tnc.c +++ b/arch/x86/cpu/queensbay/tnc.c @@ -69,17 +69,18 @@ void cpu_irq_init(void) * Route TunnelCreek PCI device interrupt pin to PIRQ * * Since PCIe downstream ports received INTx are routed to PIRQ - * A/B/C/D directly and not configurable, we route internal PCI - * device's INTx to PIRQ E/F/G/H. + * A/B/C/D directly and not configurable, we have to route PCIe + * root ports' INTx to PIRQ A/B/C/D as well. For other devices + * on TunneCreek, route them to PIRQ E/F/G/H. */ writew(PIRQE, &rcba->d02ir); writew(PIRQF, &rcba->d03ir); writew(PIRQG, &rcba->d27ir); writew(PIRQH, &rcba->d31ir); - writew(PIRQE, &rcba->d23ir); - writew(PIRQF, &rcba->d24ir); - writew(PIRQG, &rcba->d25ir); - writew(PIRQH, &rcba->d26ir); + writew(PIRQA, &rcba->d23ir); + writew(PIRQB, &rcba->d24ir); + writew(PIRQC, &rcba->d25ir); + writew(PIRQD, &rcba->d26ir); } int arch_misc_init(void) diff --git a/arch/x86/cpu/start.S b/arch/x86/cpu/start.S index 2e5f9da756..00e585e19b 100644 --- a/arch/x86/cpu/start.S +++ b/arch/x86/cpu/start.S @@ -116,12 +116,16 @@ car_init_ret: rep stosb #ifdef CONFIG_HAVE_FSP + test %esi, %esi + jz skip_hob + /* Store HOB list */ movl %esp, %edx addl $GD_HOB_LIST, %edx movl %esi, (%edx) -#endif +skip_hob: +#endif /* Setup first parameter to setup_gdt, pointer to global_data */ movl %esp, %eax diff --git a/arch/x86/cpu/start16.S b/arch/x86/cpu/start16.S index 826e2b4361..5eb17f15c9 100644 --- a/arch/x86/cpu/start16.S +++ b/arch/x86/cpu/start16.S @@ -71,11 +71,12 @@ idt_ptr: */ gdt_ptr: .word 0x1f /* limit (31 bytes = 4 GDT entries - 1) */ - .long BOOT_SEG + gdt /* base */ + .long BOOT_SEG + gdt_rom /* base */ /* Some CPUs are picky about GDT alignment... */ .align 16 -gdt: +.globl gdt_rom +gdt_rom: /* * The GDT table ... * diff --git a/arch/x86/dts/crownbay.dts b/arch/x86/dts/crownbay.dts index d68efda8df..60da1f544b 100644 --- a/arch/x86/dts/crownbay.dts +++ b/arch/x86/dts/crownbay.dts @@ -10,6 +10,7 @@ /include/ "skeleton.dtsi" /include/ "serial.dtsi" +/include/ "rtc.dtsi" / { model = "Intel Crown Bay"; @@ -23,6 +24,26 @@ silent_console = <0>; }; + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "cpu-x86"; + reg = <0>; + intel,apic-id = <0>; + }; + + cpu@1 { + device_type = "cpu"; + compatible = "cpu-x86"; + reg = <1>; + intel,apic-id = <1>; + }; + + }; + gpioa { compatible = "intel,ich6-gpio"; u-boot,dm-pre-reloc; @@ -148,10 +169,22 @@ /* TunnelCreek PCI devices */ PCI_BDF(0, 2, 0) INTA PIRQE PCI_BDF(0, 3, 0) INTA PIRQF - PCI_BDF(0, 23, 0) INTA PIRQE - PCI_BDF(0, 24, 0) INTA PIRQF - PCI_BDF(0, 25, 0) INTA PIRQG - PCI_BDF(0, 26, 0) INTA PIRQH + PCI_BDF(0, 23, 0) INTA PIRQA + PCI_BDF(0, 23, 0) INTB PIRQB + PCI_BDF(0, 23, 0) INTC PIRQC + PCI_BDF(0, 23, 0) INTD PIRQD + PCI_BDF(0, 24, 0) INTA PIRQB + PCI_BDF(0, 24, 0) INTB PIRQC + PCI_BDF(0, 24, 0) INTC PIRQD + PCI_BDF(0, 24, 0) INTD PIRQA + PCI_BDF(0, 25, 0) INTA PIRQC + PCI_BDF(0, 25, 0) INTB PIRQD + PCI_BDF(0, 25, 0) INTC PIRQA + PCI_BDF(0, 25, 0) INTD PIRQB + PCI_BDF(0, 26, 0) INTA PIRQD + PCI_BDF(0, 26, 0) INTB PIRQA + PCI_BDF(0, 26, 0) INTC PIRQB + PCI_BDF(0, 26, 0) INTD PIRQC PCI_BDF(0, 27, 0) INTA PIRQG /* * Topcliff PCI devices @@ -159,29 +192,29 @@ * Note on the Crown Bay board, Topcliff chipset * is connected to TunnelCreek PCIe port 0, so * its bus number is 1 for its PCIe port and 2 - * for its PCI devices per U-Boot currnet PCI + * for its PCI devices per U-Boot current PCI * bus enumeration algorithm. */ PCI_BDF(1, 0, 0) INTA PIRQA PCI_BDF(2, 0, 1) INTA PIRQA PCI_BDF(2, 0, 2) INTA PIRQA - PCI_BDF(2, 2, 0) INTB PIRQB - PCI_BDF(2, 2, 1) INTB PIRQB - PCI_BDF(2, 2, 2) INTB PIRQB - PCI_BDF(2, 2, 3) INTB PIRQB - PCI_BDF(2, 2, 4) INTB PIRQB + PCI_BDF(2, 2, 0) INTB PIRQD + PCI_BDF(2, 2, 1) INTB PIRQD + PCI_BDF(2, 2, 2) INTB PIRQD + PCI_BDF(2, 2, 3) INTB PIRQD + PCI_BDF(2, 2, 4) INTB PIRQD PCI_BDF(2, 4, 0) INTC PIRQC PCI_BDF(2, 4, 1) INTC PIRQC - PCI_BDF(2, 6, 0) INTD PIRQD + PCI_BDF(2, 6, 0) INTD PIRQB PCI_BDF(2, 8, 0) INTA PIRQA PCI_BDF(2, 8, 1) INTA PIRQA PCI_BDF(2, 8, 2) INTA PIRQA PCI_BDF(2, 8, 3) INTA PIRQA - PCI_BDF(2, 10, 0) INTB PIRQB - PCI_BDF(2, 10, 1) INTB PIRQB - PCI_BDF(2, 10, 2) INTB PIRQB - PCI_BDF(2, 10, 3) INTB PIRQB - PCI_BDF(2, 10, 4) INTB PIRQB + PCI_BDF(2, 10, 0) INTB PIRQD + PCI_BDF(2, 10, 1) INTB PIRQD + PCI_BDF(2, 10, 2) INTB PIRQD + PCI_BDF(2, 10, 3) INTB PIRQD + PCI_BDF(2, 10, 4) INTB PIRQD PCI_BDF(2, 12, 0) INTC PIRQC PCI_BDF(2, 12, 1) INTC PIRQC PCI_BDF(2, 12, 2) INTC PIRQC diff --git a/arch/x86/dts/minnowmax.dts b/arch/x86/dts/minnowmax.dts index bd21bfb0b4..0e59b18d34 100644 --- a/arch/x86/dts/minnowmax.dts +++ b/arch/x86/dts/minnowmax.dts @@ -111,6 +111,16 @@ }; + pci { + compatible = "intel,pci-baytrail", "pci-x86"; + #address-cells = <3>; + #size-cells = <2>; + u-boot,dm-pre-reloc; + ranges = <0x02000000 0x0 0xd0000000 0xd0000000 0 0x10000000 + 0x42000000 0x0 0xc0000000 0xc0000000 0 0x10000000 + 0x01000000 0x0 0x2000 0x2000 0 0xe000>; + }; + spi { #address-cells = <1>; #size-cells = <0>; diff --git a/arch/x86/dts/rtc.dtsi b/arch/x86/dts/rtc.dtsi new file mode 100644 index 0000000000..93dacd7307 --- /dev/null +++ b/arch/x86/dts/rtc.dtsi @@ -0,0 +1,6 @@ +/ { + rtc { + compatible = "motorola,mc146818"; + reg = <0x70 2>; + }; +}; diff --git a/arch/x86/include/asm/arch-ivybridge/bd82x6x.h b/arch/x86/include/asm/arch-ivybridge/bd82x6x.h index 5ae32f7883..7786493be7 100644 --- a/arch/x86/include/asm/arch-ivybridge/bd82x6x.h +++ b/arch/x86/include/asm/arch-ivybridge/bd82x6x.h @@ -16,7 +16,19 @@ int gma_func0_init(pci_dev_t dev, struct pci_controller *hose, const void *blob, int node); int bd82x6x_init(void); -struct x86_cpu_priv; +/** + * struct x86_cpu_priv - Information about a single CPU + * + * @apic_id: Advanced Programmable Interrupt Controller Identifier, which is + * just a number representing the CPU core + * + * TODO: Move this to driver model once lifecycle is understood + */ +struct x86_cpu_priv { + int apic_id; + int start_err; +}; + int model_206ax_init(struct x86_cpu_priv *cpu); #endif diff --git a/arch/x86/include/asm/cpu.h b/arch/x86/include/asm/cpu.h index ebc74adbc3..08284ee295 100644 --- a/arch/x86/include/asm/cpu.h +++ b/arch/x86/include/asm/cpu.h @@ -197,20 +197,6 @@ const char *cpu_vendor_name(int vendor); char *cpu_get_name(char *name); /** - * -* x86_cpu_get_desc() - Get a description string for an x86 CPU -* -* This uses cpu_get_name() and is suitable to use as the get_desc() method for -* the CPU uclass. -* -* @dev: Device to check (UCLASS_CPU) -* @buf: Buffer to place string -* @size: Size of string space -* @return 0 if OK, -ENOSPC if buffer is too small, other -ve on error -*/ -int x86_cpu_get_desc(struct udevice *dev, char *buf, int size); - -/** * cpu_call64() - Jump to a 64-bit Linux kernel (internal function) * * The kernel is uncompressed and the 64-bit entry point is expected to be diff --git a/arch/x86/include/asm/cpu_x86.h b/arch/x86/include/asm/cpu_x86.h new file mode 100644 index 0000000000..19404805c5 --- /dev/null +++ b/arch/x86/include/asm/cpu_x86.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _ASM_CPU_X86_H +#define _ASM_CPU_X86_H + +/** + * cpu_x86_bind() - Bind an x86 CPU with the driver + * + * This updates cpu device's platform data with information from device tree, + * like the processor local apic id. + * + * @dev: Device to check (UCLASS_CPU) + * @return 0 always + */ +int cpu_x86_bind(struct udevice *dev); + +/** + * cpu_x86_get_desc() - Get a description string for an x86 CPU + * + * This uses cpu_get_name() and is suitable to use as the get_desc() method for + * the CPU uclass. + * + * @dev: Device to check (UCLASS_CPU) + * @buf: Buffer to place string + * @size: Size of string space + * @return: 0 if OK, -ENOSPC if buffer is too small, other -ve on error + */ +int cpu_x86_get_desc(struct udevice *dev, char *buf, int size); + +#endif /* _ASM_CPU_X86_H */ diff --git a/arch/x86/include/asm/ioapic.h b/arch/x86/include/asm/ioapic.h index 699160f9f7..77c443e9f5 100644 --- a/arch/x86/include/asm/ioapic.h +++ b/arch/x86/include/asm/ioapic.h @@ -10,29 +10,33 @@ #define __ASM_IOAPIC_H #define IO_APIC_ADDR 0xfec00000 -#define IO_APIC_INDEX IO_APIC_ADDR + +/* Direct addressed register */ +#define IO_APIC_INDEX (IO_APIC_ADDR + 0x00) #define IO_APIC_DATA (IO_APIC_ADDR + 0x10) -#define IO_APIC_INTERRUPTS 24 -#define ALL (0xff << 24) -#define NONE 0 -#define DISABLED (1 << 16) -#define ENABLED (0 << 16) -#define TRIGGER_EDGE (0 << 15) -#define TRIGGER_LEVEL (1 << 15) -#define POLARITY_HIGH (0 << 13) -#define POLARITY_LOW (1 << 13) -#define PHYSICAL_DEST (0 << 11) -#define LOGICAL_DEST (1 << 11) -#define ExtINT (7 << 8) -#define NMI (4 << 8) -#define SMI (2 << 8) -#define INT (1 << 8) +/* Indirect addressed register offset */ +#define IO_APIC_ID 0x00 +#define IO_APIC_VER 0x01 + +/** + * io_apic_read() - Read I/O APIC register + * + * This routine reads I/O APIC indirect addressed register. + * + * @reg: address of indirect addressed register + * @return: register value to read + */ +u32 io_apic_read(u32 reg); -u32 io_apic_read(u32 ioapic_base, u32 reg); -void io_apic_write(u32 ioapic_base, u32 reg, u32 value); -void set_ioapic_id(u32 ioapic_base, u8 ioapic_id); -void setup_ioapic(u32 ioapic_base, u8 ioapic_id); -void clear_ioapic(u32 ioapic_base); +/** + * io_apic_write() - Write I/O APIC register + * + * This routine writes I/O APIC indirect addressed register. + * + * @reg: address of indirect addressed register + * @val: register value to write + */ +void io_apic_write(u32 reg, u32 val); #endif diff --git a/arch/x86/include/asm/lapic.h b/arch/x86/include/asm/lapic.h index 0a7f443195..bc2b2d1520 100644 --- a/arch/x86/include/asm/lapic.h +++ b/arch/x86/include/asm/lapic.h @@ -1,5 +1,5 @@ /* - * From Coreboot file of same name + * From coreboot file of same name * * Copyright (C) 2014 Google, Inc * @@ -9,171 +9,70 @@ #ifndef _ARCH_ASM_LAPIC_H #define _ARCH_ASM_LAPIC_H -#include <asm/io.h> -#include <asm/lapic_def.h> -#include <asm/msr.h> -#include <asm/processor.h> - -/* See if I need to initialize the local apic */ -#if CONFIG_SMP || CONFIG_IOAPIC -# define NEED_LAPIC 1 -#else -# define NEED_LAPIC 0 -#endif - -static inline __attribute__((always_inline)) - unsigned long lapic_read(unsigned long reg) -{ - return readl(LAPIC_DEFAULT_BASE + reg); -} - -static inline __attribute__((always_inline)) - void lapic_write(unsigned long reg, unsigned long val) -{ - writel(val, LAPIC_DEFAULT_BASE + reg); -} - -static inline __attribute__((always_inline)) void lapic_wait_icr_idle(void) -{ - do { } while (lapic_read(LAPIC_ICR) & LAPIC_ICR_BUSY); -} - -static inline void enable_lapic(void) -{ - msr_t msr; - - msr = msr_read(LAPIC_BASE_MSR); - msr.hi &= 0xffffff00; - msr.lo |= LAPIC_BASE_MSR_ENABLE; - msr.lo &= ~LAPIC_BASE_MSR_ADDR_MASK; - msr.lo |= LAPIC_DEFAULT_BASE; - msr_write(LAPIC_BASE_MSR, msr); -} - -static inline void disable_lapic(void) -{ - msr_t msr; - - msr = msr_read(LAPIC_BASE_MSR); - msr.lo &= ~(1 << 11); - msr_write(LAPIC_BASE_MSR, msr); -} - -static inline __attribute__((always_inline)) unsigned long lapicid(void) -{ - return lapic_read(LAPIC_ID) >> 24; -} - -#if !CONFIG_AP_IN_SIPI_WAIT -/* If we need to go back to sipi wait, we use the long non-inlined version of - * this function in lapic_cpu_init.c - */ -static inline __attribute__((always_inline)) void stop_this_cpu(void) -{ - /* Called by an AP when it is ready to halt and wait for a new task */ - for (;;) - cpu_hlt(); -} -#else -void stop_this_cpu(void); -#endif - -#define xchg(ptr, v) ((__typeof__(*(ptr)))__xchg((unsigned long)(v), (ptr), \ - sizeof(*(ptr)))) - -struct __xchg_dummy { unsigned long a[100]; }; -#define __xg(x) ((struct __xchg_dummy *)(x)) - -/* - * Note: no "lock" prefix even on SMP: xchg always implies lock anyway - * Note 2: xchg has side effect, so that attribute volatile is necessary, - * but generally the primitive is invalid, *ptr is output argument. --ANK - */ -static inline unsigned long __xchg(unsigned long x, volatile void *ptr, - int size) -{ - switch (size) { - case 1: - __asm__ __volatile__("xchgb %b0,%1" - : "=q" (x) - : "m" (*__xg(ptr)), "0" (x) - : "memory"); - break; - case 2: - __asm__ __volatile__("xchgw %w0,%1" - : "=r" (x) - : "m" (*__xg(ptr)), "0" (x) - : "memory"); - break; - case 4: - __asm__ __volatile__("xchgl %0,%1" - : "=r" (x) - : "m" (*__xg(ptr)), "0" (x) - : "memory"); - break; - } - - return x; -} - -static inline void lapic_write_atomic(unsigned long reg, unsigned long v) -{ - (void)xchg((volatile unsigned long *)(LAPIC_DEFAULT_BASE + reg), v); -} - - -#ifdef X86_GOOD_APIC -# define FORCE_READ_AROUND_WRITE 0 -# define lapic_read_around(x) lapic_read(x) -# define lapic_write_around(x, y) lapic_write((x), (y)) -#else -# define FORCE_READ_AROUND_WRITE 1 -# define lapic_read_around(x) lapic_read(x) -# define lapic_write_around(x, y) lapic_write_atomic((x), (y)) -#endif - -static inline int lapic_remote_read(int apicid, int reg, unsigned long *pvalue) -{ - int timeout; - unsigned long status; - int result; - lapic_wait_icr_idle(); - lapic_write_around(LAPIC_ICR2, SET_LAPIC_DEST_FIELD(apicid)); - lapic_write_around(LAPIC_ICR, LAPIC_DM_REMRD | (reg >> 4)); - timeout = 0; - do { - status = lapic_read(LAPIC_ICR) & LAPIC_ICR_RR_MASK; - } while (status == LAPIC_ICR_RR_INPROG && timeout++ < 1000); - - result = -1; - if (status == LAPIC_ICR_RR_VALID) { - *pvalue = lapic_read(LAPIC_RRR); - result = 0; - } - return result; -} - +#define LAPIC_DEFAULT_BASE 0xfee00000 + +#define LAPIC_ID 0x020 +#define LAPIC_LVR 0x030 + +#define LAPIC_TASKPRI 0x080 +#define LAPIC_TPRI_MASK 0xff + +#define LAPIC_RRR 0x0c0 + +#define LAPIC_SPIV 0x0f0 +#define LAPIC_SPIV_ENABLE 0x100 + +#define LAPIC_ICR 0x300 +#define LAPIC_DEST_SELF 0x40000 +#define LAPIC_DEST_ALLINC 0x80000 +#define LAPIC_DEST_ALLBUT 0xc0000 +#define LAPIC_ICR_RR_MASK 0x30000 +#define LAPIC_ICR_RR_INVALID 0x00000 +#define LAPIC_ICR_RR_INPROG 0x10000 +#define LAPIC_ICR_RR_VALID 0x20000 +#define LAPIC_INT_LEVELTRIG 0x08000 +#define LAPIC_INT_ASSERT 0x04000 +#define LAPIC_ICR_BUSY 0x01000 +#define LAPIC_DEST_LOGICAL 0x00800 +#define LAPIC_DM_FIXED 0x00000 +#define LAPIC_DM_LOWEST 0x00100 +#define LAPIC_DM_SMI 0x00200 +#define LAPIC_DM_REMRD 0x00300 +#define LAPIC_DM_NMI 0x00400 +#define LAPIC_DM_INIT 0x00500 +#define LAPIC_DM_STARTUP 0x00600 +#define LAPIC_DM_EXTINT 0x00700 +#define LAPIC_VECTOR_MASK 0x000ff + +#define LAPIC_ICR2 0x310 +#define GET_LAPIC_DEST_FIELD(x) (((x) >> 24) & 0xff) +#define SET_LAPIC_DEST_FIELD(x) ((x) << 24) + +#define LAPIC_LVT0 0x350 +#define LAPIC_LVT1 0x360 +#define LAPIC_LVT_MASKED (1 << 16) +#define LAPIC_LVT_LEVEL_TRIGGER (1 << 15) +#define LAPIC_LVT_REMOTE_IRR (1 << 14) +#define LAPIC_INPUT_POLARITY (1 << 13) +#define LAPIC_SEND_PENDING (1 << 12) +#define LAPIC_LVT_RESERVED_1 (1 << 11) +#define LAPIC_DELIVERY_MODE_MASK (7 << 8) +#define LAPIC_DELIVERY_MODE_FIXED (0 << 8) +#define LAPIC_DELIVERY_MODE_NMI (4 << 8) +#define LAPIC_DELIVERY_MODE_EXTINT (7 << 8) + +unsigned long lapic_read(unsigned long reg); + +void lapic_write(unsigned long reg, unsigned long v); + +void enable_lapic(void); + +void disable_lapic(void); + +unsigned long lapicid(void); + +int lapic_remote_read(int apicid, int reg, unsigned long *pvalue); void lapic_setup(void); -#if CONFIG_SMP -struct device; -int start_cpu(struct device *cpu); -#endif /* CONFIG_SMP */ - -int boot_cpu(void); - -/** - * struct x86_cpu_priv - Information about a single CPU - * - * @apic_id: Advanced Programmable Interrupt Controller Identifier, which is - * just a number representing the CPU core - * - * TODO: Move this to driver model once lifecycle is understood - */ -struct x86_cpu_priv { - int apic_id; - int start_err; -}; - #endif diff --git a/arch/x86/include/asm/lapic_def.h b/arch/x86/include/asm/lapic_def.h deleted file mode 100644 index 722ceadaa4..0000000000 --- a/arch/x86/include/asm/lapic_def.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Taken from the Coreboot file of the same name - * - * (C) Copyright 2014 Google, Inc - * - * SPDX-License-Identifier: GPL-2.0 - */ - -#ifndef _ASM_LAPIC_DEF_H -#define _ASM_LAPIC_DEF_H - -#define LAPIC_BASE_MSR 0x1B -#define LAPIC_BASE_MSR_BOOTSTRAP_PROCESSOR (1 << 8) -#define LAPIC_BASE_MSR_ENABLE (1 << 11) -#define LAPIC_BASE_MSR_ADDR_MASK 0xFFFFF000 - -#define LOCAL_APIC_ADDR 0xfee00000 -#define LAPIC_DEFAULT_BASE LOCAL_APIC_ADDR - -#define LAPIC_ID 0x020 -#define LAPIC_LVR 0x030 -#define LAPIC_TASKPRI 0x80 -#define LAPIC_TPRI_MASK 0xFF -#define LAPIC_ARBID 0x090 -#define LAPIC_RRR 0x0C0 -#define LAPIC_SVR 0x0f0 -#define LAPIC_SPIV 0x0f0 -#define LAPIC_SPIV_ENABLE 0x100 -#define LAPIC_ESR 0x280 -#define LAPIC_ESR_SEND_CS 0x00001 -#define LAPIC_ESR_RECV_CS 0x00002 -#define LAPIC_ESR_SEND_ACC 0x00004 -#define LAPIC_ESR_RECV_ACC 0x00008 -#define LAPIC_ESR_SENDILL 0x00020 -#define LAPIC_ESR_RECVILL 0x00040 -#define LAPIC_ESR_ILLREGA 0x00080 -#define LAPIC_ICR 0x300 -#define LAPIC_DEST_SELF 0x40000 -#define LAPIC_DEST_ALLINC 0x80000 -#define LAPIC_DEST_ALLBUT 0xC0000 -#define LAPIC_ICR_RR_MASK 0x30000 -#define LAPIC_ICR_RR_INVALID 0x00000 -#define LAPIC_ICR_RR_INPROG 0x10000 -#define LAPIC_ICR_RR_VALID 0x20000 -#define LAPIC_INT_LEVELTRIG 0x08000 -#define LAPIC_INT_ASSERT 0x04000 -#define LAPIC_ICR_BUSY 0x01000 -#define LAPIC_DEST_LOGICAL 0x00800 -#define LAPIC_DM_FIXED 0x00000 -#define LAPIC_DM_LOWEST 0x00100 -#define LAPIC_DM_SMI 0x00200 -#define LAPIC_DM_REMRD 0x00300 -#define LAPIC_DM_NMI 0x00400 -#define LAPIC_DM_INIT 0x00500 -#define LAPIC_DM_STARTUP 0x00600 -#define LAPIC_DM_EXTINT 0x00700 -#define LAPIC_VECTOR_MASK 0x000FF -#define LAPIC_ICR2 0x310 -#define GET_LAPIC_DEST_FIELD(x) (((x) >> 24) & 0xFF) -#define SET_LAPIC_DEST_FIELD(x) ((x) << 24) -#define LAPIC_LVTT 0x320 -#define LAPIC_LVTPC 0x340 -#define LAPIC_LVT0 0x350 -#define LAPIC_LVT_TIMER_BASE_MASK (0x3 << 18) -#define GET_LAPIC_TIMER_BASE(x) (((x) >> 18) & 0x3) -#define SET_LAPIC_TIMER_BASE(x) (((x) << 18)) -#define LAPIC_TIMER_BASE_CLKIN 0x0 -#define LAPIC_TIMER_BASE_TMBASE 0x1 -#define LAPIC_TIMER_BASE_DIV 0x2 -#define LAPIC_LVT_TIMER_PERIODIC (1 << 17) -#define LAPIC_LVT_MASKED (1 << 16) -#define LAPIC_LVT_LEVEL_TRIGGER (1 << 15) -#define LAPIC_LVT_REMOTE_IRR (1 << 14) -#define LAPIC_INPUT_POLARITY (1 << 13) -#define LAPIC_SEND_PENDING (1 << 12) -#define LAPIC_LVT_RESERVED_1 (1 << 11) -#define LAPIC_DELIVERY_MODE_MASK (7 << 8) -#define LAPIC_DELIVERY_MODE_FIXED (0 << 8) -#define LAPIC_DELIVERY_MODE_NMI (4 << 8) -#define LAPIC_DELIVERY_MODE_EXTINT (7 << 8) -#define GET_LAPIC_DELIVERY_MODE(x) (((x) >> 8) & 0x7) -#define SET_LAPIC_DELIVERY_MODE(x, y) (((x) & ~0x700)|((y) << 8)) -#define LAPIC_MODE_FIXED 0x0 -#define LAPIC_MODE_NMI 0x4 -#define LAPIC_MODE_EXINT 0x7 -#define LAPIC_LVT1 0x360 -#define LAPIC_LVTERR 0x370 -#define LAPIC_TMICT 0x380 -#define LAPIC_TMCCT 0x390 -#define LAPIC_TDCR 0x3E0 -#define LAPIC_TDR_DIV_TMBASE (1 << 2) -#define LAPIC_TDR_DIV_1 0xB -#define LAPIC_TDR_DIV_2 0x0 -#define LAPIC_TDR_DIV_4 0x1 -#define LAPIC_TDR_DIV_8 0x2 -#define LAPIC_TDR_DIV_16 0x3 -#define LAPIC_TDR_DIV_32 0x8 -#define LAPIC_TDR_DIV_64 0x9 -#define LAPIC_TDR_DIV_128 0xA - -#endif diff --git a/arch/x86/include/asm/mp.h b/arch/x86/include/asm/mp.h index c0930fd0c6..2e6c3120c7 100644 --- a/arch/x86/include/asm/mp.h +++ b/arch/x86/include/asm/mp.h @@ -59,7 +59,6 @@ struct mp_flight_record { * SMM support. */ struct mp_params { - int num_cpus; /* Total cpus include BSP */ int parallel_microcode_load; const void *microcode_pointer; /* Flight plan for APs and BSP */ diff --git a/arch/x86/include/asm/mpspec.h b/arch/x86/include/asm/mpspec.h new file mode 100644 index 0000000000..efa9231f92 --- /dev/null +++ b/arch/x86/include/asm/mpspec.h @@ -0,0 +1,444 @@ +/* + * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com> + * + * Adapted from coreboot src/arch/x86/include/arch/smp/mpspec.h + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ASM_MPSPEC_H +#define __ASM_MPSPEC_H + +/* + * Structure definitions for SMP machines following the + * Intel MultiProcessor Specification 1.4 + */ + +#define MPSPEC_V14 4 + +#define MPF_SIGNATURE "_MP_" + +struct mp_floating_table { + char mpf_signature[4]; /* "_MP_" */ + u32 mpf_physptr; /* Configuration table address */ + u8 mpf_length; /* Our length (paragraphs) */ + u8 mpf_spec; /* Specification version */ + u8 mpf_checksum; /* Checksum (makes sum 0) */ + u8 mpf_feature1; /* Predefined or Unique configuration? */ + u8 mpf_feature2; /* Bit7 set for IMCR/PIC */ + u8 mpf_feature3; /* Unused (0) */ + u8 mpf_feature4; /* Unused (0) */ + u8 mpf_feature5; /* Unused (0) */ +}; + +#define MPC_SIGNATURE "PCMP" + +struct mp_config_table { + char mpc_signature[4]; /* "PCMP" */ + u16 mpc_length; /* Size of table */ + u8 mpc_spec; /* Specification version */ + u8 mpc_checksum; /* Checksum (makes sum 0) */ + char mpc_oem[8]; /* OEM ID */ + char mpc_product[12]; /* Product ID */ + u32 mpc_oemptr; /* OEM table address */ + u16 mpc_oemsize; /* OEM table size */ + u16 mpc_entry_count; /* Number of entries in the table */ + u32 mpc_lapic; /* Local APIC address */ + u16 mpe_length; /* Extended table size */ + u8 mpe_checksum; /* Extended table checksum */ + u8 reserved; +}; + +/* Base MP configuration table entry types */ + +enum mp_base_config_entry_type { + MP_PROCESSOR, + MP_BUS, + MP_IOAPIC, + MP_INTSRC, + MP_LINTSRC +}; + +#define MPC_CPU_EN (1 << 0) +#define MPC_CPU_BP (1 << 1) + +struct mpc_config_processor { + u8 mpc_type; + u8 mpc_apicid; + u8 mpc_apicver; + u8 mpc_cpuflag; + u32 mpc_cpusignature; + u32 mpc_cpufeature; + u32 mpc_reserved[2]; +}; + +#define BUSTYPE_CBUS "CBUS " +#define BUSTYPE_CBUSII "CBUSII" +#define BUSTYPE_EISA "EISA " +#define BUSTYPE_FUTURE "FUTURE" +#define BUSTYPE_INTERN "INTERN" +#define BUSTYPE_ISA "ISA " +#define BUSTYPE_MBI "MBI " +#define BUSTYPE_MBII "MBII " +#define BUSTYPE_MCA "MCA " +#define BUSTYPE_MPI "MPI " +#define BUSTYPE_MPSA "MPSA " +#define BUSTYPE_NUBUS "NUBUS " +#define BUSTYPE_PCI "PCI " +#define BUSTYPE_PCMCIA "PCMCIA" +#define BUSTYPE_TC "TC " +#define BUSTYPE_VL "VL " +#define BUSTYPE_VME "VME " +#define BUSTYPE_XPRESS "XPRESS" + +struct mpc_config_bus { + u8 mpc_type; + u8 mpc_busid; + u8 mpc_bustype[6]; +}; + +#define MPC_APIC_USABLE (1 << 0) + +struct mpc_config_ioapic { + u8 mpc_type; + u8 mpc_apicid; + u8 mpc_apicver; + u8 mpc_flags; + u32 mpc_apicaddr; +}; + +enum mp_irq_source_types { + MP_INT, + MP_NMI, + MP_SMI, + MP_EXTINT +}; + +#define MP_IRQ_POLARITY_DEFAULT 0x0 +#define MP_IRQ_POLARITY_HIGH 0x1 +#define MP_IRQ_POLARITY_LOW 0x3 +#define MP_IRQ_POLARITY_MASK 0x3 +#define MP_IRQ_TRIGGER_DEFAULT 0x0 +#define MP_IRQ_TRIGGER_EDGE 0x4 +#define MP_IRQ_TRIGGER_LEVEL 0xc +#define MP_IRQ_TRIGGER_MASK 0xc + +#define MP_APIC_ALL 0xff + +struct mpc_config_intsrc { + u8 mpc_type; + u8 mpc_irqtype; + u16 mpc_irqflag; + u8 mpc_srcbus; + u8 mpc_srcbusirq; + u8 mpc_dstapic; + u8 mpc_dstirq; +}; + +struct mpc_config_lintsrc { + u8 mpc_type; + u8 mpc_irqtype; + u16 mpc_irqflag; + u8 mpc_srcbusid; + u8 mpc_srcbusirq; + u8 mpc_destapic; + u8 mpc_destlint; +}; + +/* Extended MP configuration table entry types */ + +enum mp_ext_config_entry_type { + MPE_SYSTEM_ADDRESS_SPACE = 128, + MPE_BUS_HIERARCHY, + MPE_COMPAT_ADDRESS_SPACE +}; + +struct mp_ext_config { + u8 mpe_type; + u8 mpe_length; +}; + +#define ADDRESS_TYPE_IO 0 +#define ADDRESS_TYPE_MEM 1 +#define ADDRESS_TYPE_PREFETCH 2 + +struct mp_ext_system_address_space { + u8 mpe_type; + u8 mpe_length; + u8 mpe_busid; + u8 mpe_addr_type; + u32 mpe_addr_base_low; + u32 mpe_addr_base_high; + u32 mpe_addr_length_low; + u32 mpe_addr_length_high; +}; + +#define BUS_SUBTRACTIVE_DECODE (1 << 0) + +struct mp_ext_bus_hierarchy { + u8 mpe_type; + u8 mpe_length; + u8 mpe_busid; + u8 mpe_bus_info; + u8 mpe_parent_busid; + u8 reserved[3]; +}; + +#define ADDRESS_RANGE_ADD 0 +#define ADDRESS_RANGE_SUBTRACT 1 + +/* + * X100 - X3FF + * X500 - X7FF + * X900 - XBFF + * XD00 - XFFF + */ +#define RANGE_LIST_IO_ISA 0 +/* + * X3B0 - X3BB + * X3C0 - X3DF + * X7B0 - X7BB + * X7C0 - X7DF + * XBB0 - XBBB + * XBC0 - XBDF + * XFB0 - XFBB + * XFC0 - XCDF + */ +#define RANGE_LIST_IO_VGA 1 + +struct mp_ext_compat_address_space { + u8 mpe_type; + u8 mpe_length; + u8 mpe_busid; + u8 mpe_addr_modifier; + u32 mpe_range_list; +}; + +/** + * mp_next_mpc_entry() - Compute MP configuration table end to be used as + * next base table entry start address + * + * This computes the end address of current MP configuration table, without + * counting any extended configuration table entry. + * + * @mc: configuration table header address + * @return: configuration table end address + */ +static inline u32 mp_next_mpc_entry(struct mp_config_table *mc) +{ + return (u32)mc + mc->mpc_length; +} + +/** + * mp_add_mpc_entry() - Add a base MP configuration table entry + * + * This adds the base MP configuration table entry size with + * added base table entry length and increases entry count by 1. + * + * @mc: configuration table header address + * @length: length of the added table entry + */ +static inline void mp_add_mpc_entry(struct mp_config_table *mc, uint length) +{ + mc->mpc_length += length; + mc->mpc_entry_count++; +} + +/** + * mp_next_mpe_entry() - Compute MP configuration table end to be used as + * next extended table entry start address + * + * This computes the end address of current MP configuration table, + * including any extended configuration table entry. + * + * @mc: configuration table header address + * @return: configuration table end address + */ +static inline u32 mp_next_mpe_entry(struct mp_config_table *mc) +{ + return (u32)mc + mc->mpc_length + mc->mpe_length; +} + +/** + * mp_add_mpe_entry() - Add an extended MP configuration table entry + * + * This adds the extended MP configuration table entry size with + * added extended table entry length. + * + * @mc: configuration table header address + * @mpe: extended table entry base address + */ +static inline void mp_add_mpe_entry(struct mp_config_table *mc, + struct mp_ext_config *mpe) +{ + mc->mpe_length += mpe->mpe_length; +} + +/** + * mp_write_floating_table() - Write the MP floating table + * + * This writes the MP floating table, and points MP configuration table + * to its end address so that MP configuration table follows immediately + * after the floating table. + * + * @mf: MP floating table base address + * @return: MP configuration table header address + */ +struct mp_config_table *mp_write_floating_table(struct mp_floating_table *mf); + +/** + * mp_config_table_init() - Initialize the MP configuration table header + * + * This populates the MP configuration table header with valid bits. + * + * @mc: MP configuration table header address + */ +void mp_config_table_init(struct mp_config_table *mc); + +/** + * mp_write_processor() - Write a processor entry + * + * This writes a processor entry to the configuration table. + * + * @mc: MP configuration table header address + */ +void mp_write_processor(struct mp_config_table *mc); + +/** + * mp_write_bus() - Write a bus entry + * + * This writes a bus entry to the configuration table. + * + * @mc: MP configuration table header address + * @id: bus id + * @bustype: bus type name + */ +void mp_write_bus(struct mp_config_table *mc, int id, const char *bustype); + +/** + * mp_write_ioapic() - Write an I/O APIC entry + * + * This writes an I/O APIC entry to the configuration table. + * + * @mc: MP configuration table header address + * @id: I/O APIC id + * @ver: I/O APIC version + * @apicaddr: I/O APIC address + */ +void mp_write_ioapic(struct mp_config_table *mc, int id, int ver, u32 apicaddr); + +/** + * mp_write_intsrc() - Write an I/O interrupt assignment entry + * + * This writes an I/O interrupt assignment entry to the configuration table. + * + * @mc: MP configuration table header address + * @irqtype: IRQ type (INT/NMI/SMI/ExtINT) + * @irqflag: IRQ flag (level/trigger) + * @srcbus: source bus id where the interrupt comes from + * @srcbusirq: IRQ number mapped on the source bus + * @dstapic: destination I/O APIC id where the interrupt goes to + * @dstirq: destination I/O APIC pin where the interrupt goes to + */ +void mp_write_intsrc(struct mp_config_table *mc, int irqtype, int irqflag, + int srcbus, int srcbusirq, int dstapic, int dstirq); + +/** + * mp_write_pci_intsrc() - Write a PCI interrupt assignment entry + * + * This writes a PCI interrupt assignment entry to the configuration table. + * + * @mc: MP configuration table header address + * @irqtype: IRQ type (INT/NMI/SMI/ExtINT) + * @srcbus: PCI bus number where the interrupt comes from + * @dev: device number on the PCI bus + * @pin: PCI interrupt pin (INT A/B/C/D) + * @dstapic: destination I/O APIC id where the interrupt goes to + * @dstirq: destination I/O APIC pin where the interrupt goes to + */ +void mp_write_pci_intsrc(struct mp_config_table *mc, int irqtype, + int srcbus, int dev, int pin, int dstapic, int dstirq); + +/** + * mp_write_lintsrc() - Write a local interrupt assignment entry + * + * This writes a local interrupt assignment entry to the configuration table. + * + * @mc: MP configuration table header address + * @irqtype: IRQ type (INT/NMI/SMI/ExtINT) + * @irqflag: IRQ flag (level/trigger) + * @srcbus: PCI bus number where the interrupt comes from + * @srcbusirq: IRQ number mapped on the source bus + * @dstapic: destination local APIC id where the interrupt goes to + * @destlint: destination local APIC pin where the interrupt goes to + */ +void mp_write_lintsrc(struct mp_config_table *mc, int irqtype, int irqflag, + int srcbus, int srcbusirq, int destapic, int destlint); + + +/** + * mp_write_address_space() - Write a system address space entry + * + * This writes a system address space entry to the configuration table. + * + * @mc: MP configuration table header address + * @busid: bus id for the bus where system address space is mapped + * @addr_type: system address type + * @addr_base_low: starting address low + * @addr_base_high: starting address high + * @addr_length_low: address length low + * @addr_length_high: address length high + */ +void mp_write_address_space(struct mp_config_table *mc, + int busid, int addr_type, + u32 addr_base_low, u32 addr_base_high, + u32 addr_length_low, u32 addr_length_high); + +/** + * mp_write_bus_hierarchy() - Write a bus hierarchy descriptor entry + * + * This writes a bus hierarchy descriptor entry to the configuration table. + * + * @mc: MP configuration table header address + * @busid: bus id + * @bus_info: bit0 indicates if the bus is a subtractive decode bus + * @parent_busid: parent bus id + */ +void mp_write_bus_hierarchy(struct mp_config_table *mc, + int busid, int bus_info, int parent_busid); + +/** + * mp_write_compat_address_space() - Write a compat bus address space entry + * + * This writes a compatibility bus address space modifier entry to the + * configuration table. + * + * @mc: MP configuration table header address + * @busid: bus id + * @addr_modifier: add or subtract to predefined address range list + * @range_list: list of predefined address space ranges + */ +void mp_write_compat_address_space(struct mp_config_table *mc, int busid, + int addr_modifier, u32 range_list); + +/** + * mptable_finalize() - Finalize the MP table + * + * This finalizes the MP table by calculating required checksums. + * + * @mc: MP configuration table header address + * @return: MP table end address + */ +u32 mptable_finalize(struct mp_config_table *mc); + +/** + * write_mp_table() - Write MP table + * + * This writes MP table at a given address. + * + * @addr: start address to write MP table + * @return: end address of MP table + */ +u32 write_mp_table(u32 addr); + +#endif /* __ASM_MPSPEC_H */ diff --git a/arch/x86/include/asm/mtrr.h b/arch/x86/include/asm/mtrr.h index 3ad617cb4a..70762eed10 100644 --- a/arch/x86/include/asm/mtrr.h +++ b/arch/x86/include/asm/mtrr.h @@ -21,6 +21,11 @@ #define MTRR_CAP_MSR 0x0fe #define MTRR_DEF_TYPE_MSR 0x2ff +#define MTRR_CAP_SMRR (1 << 11) +#define MTRR_CAP_WC (1 << 10) +#define MTRR_CAP_FIX (1 << 8) +#define MTRR_CAP_VCNT_MASK 0xff + #define MTRR_DEF_TYPE_EN (1 << 11) #define MTRR_DEF_TYPE_FIX_EN (1 << 10) @@ -38,17 +43,17 @@ #define RANGES_PER_FIXED_MTRR 8 #define NUM_FIXED_RANGES (NUM_FIXED_MTRRS * RANGES_PER_FIXED_MTRR) -#define MTRR_FIX_64K_00000_MSR 0x250 -#define MTRR_FIX_16K_80000_MSR 0x258 -#define MTRR_FIX_16K_A0000_MSR 0x259 -#define MTRR_FIX_4K_C0000_MSR 0x268 -#define MTRR_FIX_4K_C8000_MSR 0x269 -#define MTRR_FIX_4K_D0000_MSR 0x26a -#define MTRR_FIX_4K_D8000_MSR 0x26b -#define MTRR_FIX_4K_E0000_MSR 0x26c -#define MTRR_FIX_4K_E8000_MSR 0x26d -#define MTRR_FIX_4K_F0000_MSR 0x26e -#define MTRR_FIX_4K_F8000_MSR 0x26f +#define MTRR_FIX_64K_00000_MSR 0x250 +#define MTRR_FIX_16K_80000_MSR 0x258 +#define MTRR_FIX_16K_A0000_MSR 0x259 +#define MTRR_FIX_4K_C0000_MSR 0x268 +#define MTRR_FIX_4K_C8000_MSR 0x269 +#define MTRR_FIX_4K_D0000_MSR 0x26a +#define MTRR_FIX_4K_D8000_MSR 0x26b +#define MTRR_FIX_4K_E0000_MSR 0x26c +#define MTRR_FIX_4K_E8000_MSR 0x26d +#define MTRR_FIX_4K_F0000_MSR 0x26e +#define MTRR_FIX_4K_F8000_MSR 0x26f #if !defined(__ASSEMBLER__) diff --git a/arch/x86/include/asm/tables.h b/arch/x86/include/asm/tables.h index 8146ba39b2..0aa6d9b33e 100644 --- a/arch/x86/include/asm/tables.h +++ b/arch/x86/include/asm/tables.h @@ -28,6 +28,20 @@ u8 table_compute_checksum(void *v, int len); /** + * table_fill_string() - Fill a string with pad in the configuration table + * + * This fills a string in the configuration table. It copies number of bytes + * from the source string, and if source string length is shorter than the + * required size to copy, pad the table string with the given pad character. + * + * @dest: where to fill a string + * @src: where to copy from + * @n: number of bytes to copy + * @pad: character to pad the remaining bytes + */ +void table_fill_string(char *dest, const char *src, size_t n, char pad); + +/** * write_tables() - Write x86 configuration tables * * This writes x86 configuration tables, including PIRQ routing table, diff --git a/arch/x86/include/asm/u-boot-x86.h b/arch/x86/include/asm/u-boot-x86.h index d1d21ed660..4dae365a12 100644 --- a/arch/x86/include/asm/u-boot-x86.h +++ b/arch/x86/include/asm/u-boot-x86.h @@ -8,12 +8,19 @@ #ifndef _U_BOOT_I386_H_ #define _U_BOOT_I386_H_ 1 +extern char gdt_rom[]; + /* cpu/.../cpu.c */ int arch_cpu_init(void); int x86_cpu_init_f(void); int cpu_init_f(void); void init_gd(gd_t *id, u64 *gdt_addr); void setup_gdt(gd_t *id, u64 *gdt_addr); +/* + * Setup FSP execution environment GDT to use the one we used in + * arch/x86/cpu/start16.S and reload the segment registers. + */ +void setup_fsp_gdt(void); int init_cache(void); int cleanup_before_linux(void); @@ -49,6 +56,9 @@ u32 isa_map_rom(u32 bus_addr, int size); /* arch/x86/lib/... */ int video_bios_init(void); +/* arch/x86/lib/fsp/... */ +int x86_fsp_init(void); + void board_init_f_r_trampoline(ulong) __attribute__ ((noreturn)); void board_init_f_r(void) __attribute__ ((noreturn)); diff --git a/arch/x86/include/asm/zimage.h b/arch/x86/include/asm/zimage.h index 8e7dd424ca..bf351ed3b6 100644 --- a/arch/x86/include/asm/zimage.h +++ b/arch/x86/include/asm/zimage.h @@ -38,5 +38,6 @@ struct boot_params *load_zimage(char *image, unsigned long kernel_size, ulong *load_addressp); int setup_zimage(struct boot_params *setup_base, char *cmd_line, int auto_boot, unsigned long initrd_addr, unsigned long initrd_size); +void setup_video(struct screen_info *screen_info); #endif diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile index 70ad19b263..43489fdc1f 100644 --- a/arch/x86/lib/Makefile +++ b/arch/x86/lib/Makefile @@ -15,6 +15,7 @@ obj-y += gcc.o obj-y += init_helpers.o obj-y += interrupts.o obj-y += lpc-uclass.o +obj-y += mpspec.o obj-y += cmd_mtrr.o obj-$(CONFIG_SYS_PCAT_INTERRUPTS) += pcat_interrupts.o obj-$(CONFIG_SYS_PCAT_TIMER) += pcat_timer.o diff --git a/arch/x86/lib/bios_asm.S b/arch/x86/lib/bios_asm.S index 4faa70e314..9dbf969373 100644 --- a/arch/x86/lib/bios_asm.S +++ b/arch/x86/lib/bios_asm.S @@ -246,6 +246,9 @@ __interrupt_handler_16bit = PTR_TO_REAL_MODE(.) push %fs push %gs + /* Save real mode SS */ + movw %ss, %cs:__realmode_ss + /* Clear DF to not break ABI assumptions */ cld @@ -258,12 +261,29 @@ __interrupt_handler_16bit = PTR_TO_REAL_MODE(.) enter_protected_mode + /* + * Now we are in protected mode. We need compute the right ESP based + * on saved real mode SS otherwise interrupt_handler() won't get + * correct parameters from the stack. + */ + movzwl %cs:__realmode_ss, %ecx + shll $4, %ecx + addl %ecx, %esp + /* Call the C interrupt handler */ movl $interrupt_handler, %eax call *%eax + /* Restore real mode ESP based on saved SS */ + movzwl %cs:__realmode_ss, %ecx + shll $4, %ecx + subl %ecx, %esp + enter_real_mode + /* Restore real mode SS */ + movw %cs:__realmode_ss, %ss + /* * Restore all registers, including those manipulated by the C * handler @@ -276,6 +296,9 @@ __interrupt_handler_16bit = PTR_TO_REAL_MODE(.) popal iret +__realmode_ss = PTR_TO_REAL_MODE(.) + .word 0 + .globl asm_realmode_code_size asm_realmode_code_size: .long . - asm_realmode_code diff --git a/arch/x86/lib/bios_interrupts.c b/arch/x86/lib/bios_interrupts.c index 290990a8bd..47d9f599a3 100644 --- a/arch/x86/lib/bios_interrupts.c +++ b/arch/x86/lib/bios_interrupts.c @@ -161,15 +161,7 @@ int int1a_handler(void) bus = M.x86.R_EBX >> 8; reg = M.x86.R_EDI; dev = PCI_BDF(bus, devfn >> 3, devfn & 7); - if (!dev) { - debug("0x%x: BAD DEVICE bus %d devfn 0x%x\n", func, - bus, devfn); - /* Or are we supposed to return PCIBIOS_NODEV? */ - M.x86.R_EAX &= 0xffff00ff; /* Clear AH */ - M.x86.R_EAX |= PCIBIOS_BADREG; - retval = 0; - return retval; - } + switch (func) { case 0xb108: /* Read Config Byte */ byte = x86_pci_read_config8(dev, reg); diff --git a/arch/x86/lib/cmd_mtrr.c b/arch/x86/lib/cmd_mtrr.c index 7e0506b75d..f632f495ed 100644 --- a/arch/x86/lib/cmd_mtrr.c +++ b/arch/x86/lib/cmd_mtrr.c @@ -37,7 +37,8 @@ static int do_mtrr_list(void) valid = mask & MTRR_PHYS_MASK_VALID; type = mtrr_type_name[base & MTRR_BASE_TYPE_MASK]; printf("%d %-5s %-12s %016llx %016llx %016llx\n", i, - valid ? "Y" : "N", type, base, mask, size); + valid ? "Y" : "N", type, base & ~MTRR_BASE_TYPE_MASK, + mask & ~MTRR_PHYS_MASK_VALID, size); } return 0; diff --git a/arch/x86/lib/fsp/fsp_car.S b/arch/x86/lib/fsp/fsp_car.S index 5e09568b85..afbf3f9baa 100644 --- a/arch/x86/lib/fsp/fsp_car.S +++ b/arch/x86/lib/fsp/fsp_car.S @@ -56,28 +56,10 @@ temp_ram_init_ret: /* stack grows down from top of CAR */ movl %edx, %esp + subl $4, %esp - /* - * TODO: - * - * According to FSP architecture spec, the fsp_init() will not return - * to its caller, instead it requires the bootloader to provide a - * so-called continuation function to pass into the FSP as a parameter - * of fsp_init, and fsp_init() will call that continuation function - * directly. - * - * The call to fsp_init() may need to be moved out of the car_init() - * to cpu_init_f() with the help of some inline assembly codes. - * Note there is another issue that fsp_init() will setup another stack - * using the fsp_init parameter stack_top after DRAM is initialized, - * which means any data on the previous stack (on the CAR) gets lost - * (ie: U-Boot global_data). FSP is supposed to support such scenario, - * however it does not work. This should be revisited in the future. - */ - movl $CONFIG_FSP_TEMP_RAM_ADDR, %eax - xorl %edx, %edx - xorl %ecx, %ecx - call fsp_init + xor %esi, %esi + jmp car_init_done .global fsp_init_done fsp_init_done: @@ -86,6 +68,8 @@ fsp_init_done: * Save eax to esi temporarily. */ movl %eax, %esi + +car_init_done: /* * Re-initialize the ebp (BIST) to zero, as we already reach here * which means we passed BIST testing before. diff --git a/arch/x86/lib/fsp/fsp_common.c b/arch/x86/lib/fsp/fsp_common.c index 001494d97d..5b256324e1 100644 --- a/arch/x86/lib/fsp/fsp_common.c +++ b/arch/x86/lib/fsp/fsp_common.c @@ -46,3 +46,11 @@ void board_final_cleanup(void) return; } + +int x86_fsp_init(void) +{ + if (!gd->arch.hob_list) + fsp_init(CONFIG_FSP_TEMP_RAM_ADDR, BOOT_FULL_CONFIG, NULL); + + return 0; +} diff --git a/arch/x86/lib/fsp/fsp_support.c b/arch/x86/lib/fsp/fsp_support.c index 5809235b10..4585166083 100644 --- a/arch/x86/lib/fsp/fsp_support.c +++ b/arch/x86/lib/fsp/fsp_support.c @@ -173,6 +173,9 @@ void fsp_init(u32 stack_top, u32 boot_mode, void *nvs_buf) post_code(POST_PRE_MRC); + /* Load GDT for FSP */ + setup_fsp_gdt(); + /* * Use ASM code to ensure the register value in EAX & ECX * will be passed into BlContinuationFunc diff --git a/arch/x86/lib/mpspec.c b/arch/x86/lib/mpspec.c new file mode 100644 index 0000000000..f16fbcbb0d --- /dev/null +++ b/arch/x86/lib/mpspec.c @@ -0,0 +1,382 @@ +/* + * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com> + * + * Adapted from coreboot src/arch/x86/boot/mpspec.c + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <cpu.h> +#include <dm.h> +#include <errno.h> +#include <fdtdec.h> +#include <asm/cpu.h> +#include <asm/irq.h> +#include <asm/ioapic.h> +#include <asm/lapic.h> +#include <asm/mpspec.h> +#include <asm/tables.h> +#include <dm/uclass-internal.h> + +DECLARE_GLOBAL_DATA_PTR; + +struct mp_config_table *mp_write_floating_table(struct mp_floating_table *mf) +{ + u32 mc; + + memcpy(mf->mpf_signature, MPF_SIGNATURE, 4); + mf->mpf_physptr = (u32)mf + sizeof(struct mp_floating_table); + mf->mpf_length = 1; + mf->mpf_spec = MPSPEC_V14; + mf->mpf_checksum = 0; + /* We don't use the default configuration table */ + mf->mpf_feature1 = 0; + /* Indicate that virtual wire mode is always implemented */ + mf->mpf_feature2 = 0; + mf->mpf_feature3 = 0; + mf->mpf_feature4 = 0; + mf->mpf_feature5 = 0; + mf->mpf_checksum = table_compute_checksum(mf, mf->mpf_length * 16); + + mc = (u32)mf + sizeof(struct mp_floating_table); + return (struct mp_config_table *)mc; +} + +void mp_config_table_init(struct mp_config_table *mc) +{ + memcpy(mc->mpc_signature, MPC_SIGNATURE, 4); + mc->mpc_length = sizeof(struct mp_config_table); + mc->mpc_spec = MPSPEC_V14; + mc->mpc_checksum = 0; + mc->mpc_oemptr = 0; + mc->mpc_oemsize = 0; + mc->mpc_entry_count = 0; + mc->mpc_lapic = LAPIC_DEFAULT_BASE; + mc->mpe_length = 0; + mc->mpe_checksum = 0; + mc->reserved = 0; + + /* The oem/product id fields are exactly 8/12 bytes long */ + table_fill_string(mc->mpc_oem, CONFIG_SYS_VENDOR, 8, ' '); + table_fill_string(mc->mpc_product, CONFIG_SYS_BOARD, 12, ' '); +} + +void mp_write_processor(struct mp_config_table *mc) +{ + struct mpc_config_processor *mpc; + struct udevice *dev; + u8 boot_apicid, apicver; + u32 cpusignature, cpufeature; + struct cpuid_result result; + + boot_apicid = lapicid(); + apicver = lapic_read(LAPIC_LVR) & 0xff; + result = cpuid(1); + cpusignature = result.eax; + cpufeature = result.edx; + + for (uclass_find_first_device(UCLASS_CPU, &dev); + dev; + uclass_find_next_device(&dev)) { + struct cpu_platdata *plat = dev_get_parent_platdata(dev); + u8 cpuflag = MPC_CPU_EN; + + if (!device_active(dev)) + continue; + + mpc = (struct mpc_config_processor *)mp_next_mpc_entry(mc); + mpc->mpc_type = MP_PROCESSOR; + mpc->mpc_apicid = plat->cpu_id; + mpc->mpc_apicver = apicver; + if (boot_apicid == plat->cpu_id) + cpuflag |= MPC_CPU_BP; + mpc->mpc_cpuflag = cpuflag; + mpc->mpc_cpusignature = cpusignature; + mpc->mpc_cpufeature = cpufeature; + mpc->mpc_reserved[0] = 0; + mpc->mpc_reserved[1] = 0; + mp_add_mpc_entry(mc, sizeof(*mpc)); + } +} + +void mp_write_bus(struct mp_config_table *mc, int id, const char *bustype) +{ + struct mpc_config_bus *mpc; + + mpc = (struct mpc_config_bus *)mp_next_mpc_entry(mc); + mpc->mpc_type = MP_BUS; + mpc->mpc_busid = id; + memcpy(mpc->mpc_bustype, bustype, 6); + mp_add_mpc_entry(mc, sizeof(*mpc)); +} + +void mp_write_ioapic(struct mp_config_table *mc, int id, int ver, u32 apicaddr) +{ + struct mpc_config_ioapic *mpc; + + mpc = (struct mpc_config_ioapic *)mp_next_mpc_entry(mc); + mpc->mpc_type = MP_IOAPIC; + mpc->mpc_apicid = id; + mpc->mpc_apicver = ver; + mpc->mpc_flags = MPC_APIC_USABLE; + mpc->mpc_apicaddr = apicaddr; + mp_add_mpc_entry(mc, sizeof(*mpc)); +} + +void mp_write_intsrc(struct mp_config_table *mc, int irqtype, int irqflag, + int srcbus, int srcbusirq, int dstapic, int dstirq) +{ + struct mpc_config_intsrc *mpc; + + mpc = (struct mpc_config_intsrc *)mp_next_mpc_entry(mc); + mpc->mpc_type = MP_INTSRC; + mpc->mpc_irqtype = irqtype; + mpc->mpc_irqflag = irqflag; + mpc->mpc_srcbus = srcbus; + mpc->mpc_srcbusirq = srcbusirq; + mpc->mpc_dstapic = dstapic; + mpc->mpc_dstirq = dstirq; + mp_add_mpc_entry(mc, sizeof(*mpc)); +} + +void mp_write_pci_intsrc(struct mp_config_table *mc, int irqtype, + int srcbus, int dev, int pin, int dstapic, int dstirq) +{ + u8 srcbusirq = (dev << 2) | (pin - 1); + + mp_write_intsrc(mc, irqtype, MP_IRQ_TRIGGER_LEVEL | MP_IRQ_POLARITY_LOW, + srcbus, srcbusirq, dstapic, dstirq); +} + +void mp_write_lintsrc(struct mp_config_table *mc, int irqtype, int irqflag, + int srcbus, int srcbusirq, int destapic, int destlint) +{ + struct mpc_config_lintsrc *mpc; + + mpc = (struct mpc_config_lintsrc *)mp_next_mpc_entry(mc); + mpc->mpc_type = MP_LINTSRC; + mpc->mpc_irqtype = irqtype; + mpc->mpc_irqflag = irqflag; + mpc->mpc_srcbusid = srcbus; + mpc->mpc_srcbusirq = srcbusirq; + mpc->mpc_destapic = destapic; + mpc->mpc_destlint = destlint; + mp_add_mpc_entry(mc, sizeof(*mpc)); +} + +void mp_write_address_space(struct mp_config_table *mc, + int busid, int addr_type, + u32 addr_base_low, u32 addr_base_high, + u32 addr_length_low, u32 addr_length_high) +{ + struct mp_ext_system_address_space *mpe; + + mpe = (struct mp_ext_system_address_space *)mp_next_mpe_entry(mc); + mpe->mpe_type = MPE_SYSTEM_ADDRESS_SPACE; + mpe->mpe_length = sizeof(*mpe); + mpe->mpe_busid = busid; + mpe->mpe_addr_type = addr_type; + mpe->mpe_addr_base_low = addr_base_low; + mpe->mpe_addr_base_high = addr_base_high; + mpe->mpe_addr_length_low = addr_length_low; + mpe->mpe_addr_length_high = addr_length_high; + mp_add_mpe_entry(mc, (struct mp_ext_config *)mpe); +} + +void mp_write_bus_hierarchy(struct mp_config_table *mc, + int busid, int bus_info, int parent_busid) +{ + struct mp_ext_bus_hierarchy *mpe; + + mpe = (struct mp_ext_bus_hierarchy *)mp_next_mpe_entry(mc); + mpe->mpe_type = MPE_BUS_HIERARCHY; + mpe->mpe_length = sizeof(*mpe); + mpe->mpe_busid = busid; + mpe->mpe_bus_info = bus_info; + mpe->mpe_parent_busid = parent_busid; + mpe->reserved[0] = 0; + mpe->reserved[1] = 0; + mpe->reserved[2] = 0; + mp_add_mpe_entry(mc, (struct mp_ext_config *)mpe); +} + +void mp_write_compat_address_space(struct mp_config_table *mc, int busid, + int addr_modifier, u32 range_list) +{ + struct mp_ext_compat_address_space *mpe; + + mpe = (struct mp_ext_compat_address_space *)mp_next_mpe_entry(mc); + mpe->mpe_type = MPE_COMPAT_ADDRESS_SPACE; + mpe->mpe_length = sizeof(*mpe); + mpe->mpe_busid = busid; + mpe->mpe_addr_modifier = addr_modifier; + mpe->mpe_range_list = range_list; + mp_add_mpe_entry(mc, (struct mp_ext_config *)mpe); +} + +u32 mptable_finalize(struct mp_config_table *mc) +{ + u32 end; + + mc->mpe_checksum = table_compute_checksum((void *)mp_next_mpc_entry(mc), + mc->mpe_length); + mc->mpc_checksum = table_compute_checksum(mc, mc->mpc_length); + end = mp_next_mpe_entry(mc); + + debug("Write the MP table at: %x - %x\n", (u32)mc, end); + + return end; +} + +static void mptable_add_isa_interrupts(struct mp_config_table *mc, int bus_isa, + int apicid, int external_int2) +{ + int i; + + mp_write_intsrc(mc, external_int2 ? MP_INT : MP_EXTINT, + MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH, + bus_isa, 0, apicid, 0); + mp_write_intsrc(mc, MP_INT, MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH, + bus_isa, 1, apicid, 1); + mp_write_intsrc(mc, external_int2 ? MP_EXTINT : MP_INT, + MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH, + bus_isa, 0, apicid, 2); + + for (i = 3; i < 16; i++) + mp_write_intsrc(mc, MP_INT, + MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH, + bus_isa, i, apicid, i); +} + +/* + * Check duplicated I/O interrupt assignment table entry, to make sure + * there is only one entry with the given bus, device and interrupt pin. + */ +static bool check_dup_entry(struct mpc_config_intsrc *intsrc_base, + int entry_num, int bus, int device, int pin) +{ + struct mpc_config_intsrc *intsrc = intsrc_base; + int i; + + for (i = 0; i < entry_num; i++) { + if (intsrc->mpc_srcbus == bus && + intsrc->mpc_srcbusirq == ((device << 2) | (pin - 1))) + break; + intsrc++; + } + + return (i == entry_num) ? false : true; +} + +static int mptable_add_intsrc(struct mp_config_table *mc, + int bus_isa, int apicid) +{ + struct mpc_config_intsrc *intsrc_base; + int intsrc_entries = 0; + const void *blob = gd->fdt_blob; + int node; + int len, count; + const u32 *cell; + int i; + + /* Legacy Interrupts */ + debug("Writing ISA IRQs\n"); + mptable_add_isa_interrupts(mc, bus_isa, apicid, 0); + + /* Get I/O interrupt information from device tree */ + node = fdtdec_next_compatible(blob, 0, COMPAT_INTEL_IRQ_ROUTER); + if (node < 0) { + debug("%s: Cannot find irq router node\n", __func__); + return -ENOENT; + } + + cell = fdt_getprop(blob, node, "intel,pirq-routing", &len); + if (!cell) + return -ENOENT; + + if ((len % sizeof(struct pirq_routing)) == 0) + count = len / sizeof(struct pirq_routing); + else + return -EINVAL; + + intsrc_base = (struct mpc_config_intsrc *)mp_next_mpc_entry(mc); + + for (i = 0; i < count; i++) { + struct pirq_routing pr; + + pr.bdf = fdt_addr_to_cpu(cell[0]); + pr.pin = fdt_addr_to_cpu(cell[1]); + pr.pirq = fdt_addr_to_cpu(cell[2]); + + if (check_dup_entry(intsrc_base, intsrc_entries, + PCI_BUS(pr.bdf), PCI_DEV(pr.bdf), pr.pin)) { + debug("found entry for bus %d device %d INT%c, skipping\n", + PCI_BUS(pr.bdf), PCI_DEV(pr.bdf), + 'A' + pr.pin - 1); + cell += sizeof(struct pirq_routing) / sizeof(u32); + continue; + } + + /* PIRQ[A-H] are always connected to I/O APIC INTPIN#16-23 */ + mp_write_pci_intsrc(mc, MP_INT, PCI_BUS(pr.bdf), + PCI_DEV(pr.bdf), pr.pin, apicid, + pr.pirq + 16); + intsrc_entries++; + cell += sizeof(struct pirq_routing) / sizeof(u32); + } + + return 0; +} + +static void mptable_add_lintsrc(struct mp_config_table *mc, int bus_isa) +{ + mp_write_lintsrc(mc, MP_EXTINT, + MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH, + bus_isa, 0, MP_APIC_ALL, 0); + mp_write_lintsrc(mc, MP_NMI, + MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH, + bus_isa, 0, MP_APIC_ALL, 1); +} + +u32 write_mp_table(u32 addr) +{ + struct mp_config_table *mc; + int ioapic_id, ioapic_ver; + int bus_isa = 0xff; + int ret; + u32 end; + + /* 16 byte align the table address */ + addr = ALIGN(addr, 16); + + /* Write floating table */ + mc = mp_write_floating_table((struct mp_floating_table *)addr); + + /* Write configuration table header */ + mp_config_table_init(mc); + + /* Write processor entry */ + mp_write_processor(mc); + + /* Write bus entry */ + mp_write_bus(mc, bus_isa, BUSTYPE_ISA); + + /* Write I/O APIC entry */ + ioapic_id = io_apic_read(IO_APIC_ID) >> 24; + ioapic_ver = io_apic_read(IO_APIC_VER) & 0xff; + mp_write_ioapic(mc, ioapic_id, ioapic_ver, IO_APIC_ADDR); + + /* Write I/O interrupt assignment entry */ + ret = mptable_add_intsrc(mc, bus_isa, ioapic_id); + if (ret) + debug("Failed to write I/O interrupt assignment table\n"); + + /* Write local interrupt assignment entry */ + mptable_add_lintsrc(mc, bus_isa); + + /* Finalize the MP table */ + end = mptable_finalize(mc); + + return end; +} diff --git a/arch/x86/lib/tables.c b/arch/x86/lib/tables.c index 8031201a49..75ffbc1b22 100644 --- a/arch/x86/lib/tables.c +++ b/arch/x86/lib/tables.c @@ -6,6 +6,7 @@ #include <common.h> #include <asm/sfi.h> +#include <asm/mpspec.h> #include <asm/tables.h> u8 table_compute_checksum(void *v, int len) @@ -20,6 +21,20 @@ u8 table_compute_checksum(void *v, int len) return checksum; } +void table_fill_string(char *dest, const char *src, size_t n, char pad) +{ + int start, len; + int i; + + strncpy(dest, src, n); + + /* Fill the remaining bytes with pad */ + len = strlen(src); + start = len < n ? len : n; + for (i = start; i < n; i++) + dest[i] = pad; +} + void write_tables(void) { u32 __maybe_unused rom_table_end = ROM_TABLE_ADDR; @@ -32,4 +47,8 @@ void write_tables(void) rom_table_end = write_sfi_table(rom_table_end); rom_table_end = ALIGN(rom_table_end, 1024); #endif +#ifdef CONFIG_GENERATE_MP_TABLE + rom_table_end = write_mp_table(rom_table_end); + rom_table_end = ALIGN(rom_table_end, 1024); +#endif } diff --git a/arch/x86/lib/zimage.c b/arch/x86/lib/zimage.c index c3f8a7308f..144471c5bb 100644 --- a/arch/x86/lib/zimage.c +++ b/arch/x86/lib/zimage.c @@ -273,6 +273,8 @@ int setup_zimage(struct boot_params *setup_base, char *cmd_line, int auto_boot, build_command_line(cmd_line, auto_boot); } + setup_video(&setup_base->screen_info); + return 0; } diff --git a/board/Marvell/db-88f6820-gp/MAINTAINERS b/board/Marvell/db-88f6820-gp/MAINTAINERS new file mode 100644 index 0000000000..f5649400ec --- /dev/null +++ b/board/Marvell/db-88f6820-gp/MAINTAINERS @@ -0,0 +1,6 @@ +DB_88F6820_GP BOARD +M: Stefan Roese <sr@denx.de> +S: Maintained +F: board/Marvell/db-88f6820-gp/ +F: include/configs/db-88f6820-gp.h +F: configs/db-88f6820-gp_defconfig diff --git a/board/google/chromebook_link/Kconfig b/board/google/chromebook_link/Kconfig index 9c8d0205a1..d3644a9655 100644 --- a/board/google/chromebook_link/Kconfig +++ b/board/google/chromebook_link/Kconfig @@ -22,7 +22,6 @@ config BOARD_SPECIFIC_OPTIONS # dummy select NORTHBRIDGE_INTEL_IVYBRIDGE select SOUTHBRIDGE_INTEL_C216 select HAVE_ACPI_RESUME - select MARK_GRAPHICS_MEM_WRCOMB select BOARD_ROMSIZE_KB_8192 config PCIE_ECAM_BASE diff --git a/board/google/chromebox_panther/Kconfig b/board/google/chromebox_panther/Kconfig index e3604ebe31..d56d90378c 100644 --- a/board/google/chromebox_panther/Kconfig +++ b/board/google/chromebox_panther/Kconfig @@ -23,7 +23,6 @@ config BOARD_SPECIFIC_OPTIONS # dummy select NORTHBRIDGE_INTEL_IVYBRIDGE select SOUTHBRIDGE_INTEL_C216 select HAVE_ACPI_RESUME - select MARK_GRAPHICS_MEM_WRCOMB select BOARD_ROMSIZE_KB_8192 config SYS_CAR_ADDR diff --git a/board/samsung/smdk5420/MAINTAINERS b/board/samsung/smdk5420/MAINTAINERS index a26ea689f2..0361657ede 100644 --- a/board/samsung/smdk5420/MAINTAINERS +++ b/board/samsung/smdk5420/MAINTAINERS @@ -14,3 +14,4 @@ M: Przemyslaw Marczak <p.marczak@samsung.com> S: Maintained F: board/samsung/smdk5420/ F: include/configs/odroid_xu3.h +F: configs/odroid-xu3_defconfig diff --git a/board/st/stm32f429-discovery/MAINTAINERS b/board/st/stm32f429-discovery/MAINTAINERS index 78b0d28790..641f26a037 100644 --- a/board/st/stm32f429-discovery/MAINTAINERS +++ b/board/st/stm32f429-discovery/MAINTAINERS @@ -1,3 +1,4 @@ +STM32F429-DISCOVERY BOARD M: Kamil Lulko <rev13@wp.pl> S: Maintained F: board/st/stm32f429-discovery/ diff --git a/board/st/stv0991/stv0991.c b/board/st/stv0991/stv0991.c index 09f973f403..add1ce1a79 100644 --- a/board/st/stv0991/stv0991.c +++ b/board/st/stv0991/stv0991.c @@ -55,12 +55,20 @@ int board_eth_enable(void) return 0; } +int board_qspi_enable(void) +{ + stv0991_pinmux_config(QSPI_CS_CLK_PAD); + clock_setup(QSPI_CLOCK_CFG); + return 0; +} + /* * Miscellaneous platform dependent initialisations */ int board_init(void) { board_eth_enable(); + board_qspi_enable(); return 0; } diff --git a/board/ti/beagle_x15/mux_data.h b/board/ti/beagle_x15/mux_data.h index 09d3650983..23f22a02be 100644 --- a/board/ti/beagle_x15/mux_data.h +++ b/board/ti/beagle_x15/mux_data.h @@ -244,8 +244,8 @@ const struct pad_conf_entry core_padconf_array_essential[] = { {SPI2_D1, (M14 | PIN_INPUT_PULLDOWN)}, /* spi2_d1.gpio7_15 */ {SPI2_D0, (M14 | PIN_INPUT_PULLUP)}, /* spi2_d0.gpio7_16 */ {SPI2_CS0, (M14 | PIN_INPUT_PULLUP | SLEWCONTROL)}, /* spi2_cs0.gpio7_17 */ - {DCAN1_TX, (M0 | PIN_INPUT_PULLUP | SLEWCONTROL)}, /* dcan1_tx.dcan1_tx */ - {DCAN1_RX, (M0 | PIN_INPUT_PULLUP | SLEWCONTROL)}, /* dcan1_rx.dcan1_rx */ + {DCAN1_TX, (M15 | PULL_UP)}, /* dcan1_tx.safe for dcan1_tx */ + {DCAN1_RX, (M15 | PULL_UP)}, /* dcan1_rx.safe for dcan1_rx */ {UART1_RXD, (M0 | PIN_INPUT_SLEW)}, /* uart1_rxd.uart1_rxd */ {UART1_TXD, (M0 | PIN_INPUT_SLEW)}, /* uart1_txd.uart1_txd */ {UART1_CTSN, (M15 | PIN_INPUT_PULLDOWN)}, /* uart1_ctsn.Driveroff */ diff --git a/board/ti/dra7xx/mux_data.h b/board/ti/dra7xx/mux_data.h index 5145301586..ea8ee9fb3a 100644 --- a/board/ti/dra7xx/mux_data.h +++ b/board/ti/dra7xx/mux_data.h @@ -359,7 +359,7 @@ const struct pad_conf_entry dra74x_core_padconf_array[] = { {SPI2_D1, (M1 | PIN_INPUT_SLEW)}, /* spi2_d1.uart3_txd */ {SPI2_D0, (M1 | PIN_INPUT_SLEW)}, /* spi2_d0.uart3_ctsn */ {SPI2_CS0, (M1 | PIN_INPUT_PULLUP | SLEWCONTROL)}, /* spi2_cs0.uart3_rtsn */ - {DCAN1_TX, (M0 | PIN_INPUT_PULLUP | SLEWCONTROL)}, /* dcan1_tx.dcan1_tx */ + {DCAN1_TX, (M15 | PULL_UP)}, /* dcan1_tx.safe for dcan1_tx */ {DCAN1_RX, (M14 | PIN_INPUT_PULLUP | SLEWCONTROL)}, /* dcan1_rx.gpio1_15 */ {UART1_RXD, (M0 | PIN_INPUT_PULLUP | SLEWCONTROL)}, /* uart1_rxd.uart1_rxd */ {UART1_TXD, (M0 | PIN_INPUT_PULLUP | SLEWCONTROL)}, /* uart1_txd.uart1_txd */ @@ -371,7 +371,7 @@ const struct pad_conf_entry dra74x_core_padconf_array[] = { {UART2_RTSN, (M3 | PIN_INPUT_PULLUP)}, /* uart2_rtsn.mmc4_dat3 */ {I2C2_SDA, (M0 | PIN_INPUT_PULLUP)}, /* i2c2_sda.i2c2_sda */ {I2C2_SCL, (M0 | PIN_INPUT_PULLUP)}, /* i2c2_scl.i2c2_scl */ - {WAKEUP0, (M1 | PIN_OUTPUT)}, /* Wakeup0.dcan1_rx */ + {WAKEUP0, (M15 | PULL_UP)}, /* Wakeup0.safe for dcan1_rx */ {WAKEUP2, (M14 | PIN_OUTPUT)}, /* Wakeup2.gpio1_2 */ }; diff --git a/board/vscom/baltos/board.c b/board/vscom/baltos/board.c index 99ca60e2ac..09bc8c682a 100644 --- a/board/vscom/baltos/board.c +++ b/board/vscom/baltos/board.c @@ -184,6 +184,8 @@ void am33xx_spl_board_init(void) */ i2c_set_bus_num(1); + printf("I2C speed: %d Hz\n", CONFIG_SYS_OMAP24_I2C_SPEED); + if (i2c_probe(TPS65910_CTRL_I2C_ADDR)) { puts("i2c: cannot access TPS65910\n"); return; diff --git a/common/board_f.c b/common/board_f.c index fbbad1bcb9..21be26f8e4 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -753,6 +753,9 @@ static init_fnc_t init_sequence_f[] = { #ifdef CONFIG_OF_CONTROL fdtdec_setup, #endif +#if defined(CONFIG_X86) && defined(CONFIG_HAVE_FSP) + x86_fsp_init, +#endif #ifdef CONFIG_TRACE trace_early_init, #endif diff --git a/common/cmd_cpu.c b/common/cmd_cpu.c index c3e229f00a..b4af64f54f 100644 --- a/common/cmd_cpu.c +++ b/common/cmd_cpu.c @@ -9,6 +9,7 @@ #include <command.h> #include <cpu.h> #include <dm.h> +#include <errno.h> static const char *cpu_feature_name[CPU_FEAT_COUNT] = { "L1 cache", diff --git a/common/cmd_date.c b/common/cmd_date.c index 61727e3d1f..8714699621 100644 --- a/common/cmd_date.c +++ b/common/cmd_date.c @@ -37,7 +37,7 @@ static int do_date(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) int old_bus __maybe_unused; /* switch to correct I2C bus */ -#ifdef CONFIG_DM_I2C +#ifdef CONFIG_DM_RTC struct udevice *dev; rcode = uclass_get_device(UCLASS_RTC, 0, &dev); @@ -57,7 +57,7 @@ static int do_date(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) case 2: /* set date & time */ if (strcmp(argv[1],"reset") == 0) { puts ("Reset RTC...\n"); -#ifdef CONFIG_DM_I2C +#ifdef CONFIG_DM_RTC rcode = dm_rtc_reset(dev); if (!rcode) rcode = dm_rtc_set(dev, &default_tm); @@ -69,7 +69,7 @@ static int do_date(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) puts("## Failed to set date after RTC reset\n"); } else { /* initialize tm with current time */ -#ifdef CONFIG_DM_I2C +#ifdef CONFIG_DM_RTC rcode = dm_rtc_get(dev, &tm); #else rcode = rtc_get(&tm); @@ -81,7 +81,7 @@ static int do_date(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) break; } /* and write to RTC */ -#ifdef CONFIG_DM_I2C +#ifdef CONFIG_DM_RTC rcode = dm_rtc_set(dev, &tm); #else rcode = rtc_set(&tm); @@ -96,7 +96,7 @@ static int do_date(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) } /* FALL TROUGH */ case 1: /* get date & time */ -#ifdef CONFIG_DM_I2C +#ifdef CONFIG_DM_RTC rcode = dm_rtc_get(dev, &tm); #else rcode = rtc_get(&tm); @@ -120,7 +120,7 @@ static int do_date(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) /* switch back to original I2C bus */ #ifdef CONFIG_SYS_I2C i2c_set_bus_num(old_bus); -#elif !defined(CONFIG_DM_I2C) +#elif !defined(CONFIG_DM_RTC) I2C_SET_BUS(old_bus); #endif diff --git a/common/cmd_scsi.c b/common/cmd_scsi.c index aaca3e8a2a..31c43195e4 100644 --- a/common/cmd_scsi.c +++ b/common/cmd_scsi.c @@ -368,7 +368,7 @@ static ulong scsi_read(int device, lbaint_t blknr, lbaint_t blkcnt, { lbaint_t start, blks; uintptr_t buf_addr; - unsigned short smallblks; + unsigned short smallblks = 0; ccb* pccb=(ccb *)&tempccb; device&=0xff; /* Setup device @@ -391,7 +391,7 @@ static ulong scsi_read(int device, lbaint_t blknr, lbaint_t blkcnt, scsi_setup_read16(pccb, start, blocks); start += blocks; blks -= blocks; - } else + } else #endif if (blks > SCSI_MAX_READ_BLK) { pccb->datalen=scsi_dev_desc[device].blksz * SCSI_MAX_READ_BLK; diff --git a/common/cmd_sf.c b/common/cmd_sf.c index aef8c2a5ea..3746e0d964 100644 --- a/common/cmd_sf.c +++ b/common/cmd_sf.c @@ -303,8 +303,12 @@ static int do_spi_flash_read_write(int argc, char * const argv[]) else ret = spi_flash_write(flash, offset, len, buf); - printf("SF: %zu bytes @ %#x %s: %s\n", (size_t)len, (u32)offset, - read ? "Read" : "Written", ret ? "ERROR" : "OK"); + printf("SF: %zu bytes @ %#x %s: ", (size_t)len, (u32)offset, + read ? "Read" : "Written"); + if (ret) + printf("ERROR %d\n", ret); + else + printf("OK\n"); } unmap_physmem(buf, len); diff --git a/configs/am335x_baltos_defconfig b/configs/am335x_baltos_defconfig index bf73919c06..8e8a897ef8 100644 --- a/configs/am335x_baltos_defconfig +++ b/configs/am335x_baltos_defconfig @@ -3,9 +3,9 @@ CONFIG_TARGET_AM335X_BALTOS=y CONFIG_SPL=y CONFIG_SPL_STACK_R=y CONFIG_SPL_STACK_R_ADDR=0x82000000 +CONFIG_FIT=y +CONFIG_FIT_VERBOSE=y CONFIG_SYS_EXTRA_OPTIONS="NAND" -CONFIG_CONS_INDEX=1 # CONFIG_CMD_IMLS is not set # CONFIG_CMD_FLASH is not set # CONFIG_CMD_SETEXPR is not set -# CONFIG_CMD_NET is not set diff --git a/configs/bf533-stamp_defconfig b/configs/bf533-stamp_defconfig index 154dc26909..4956078e61 100644 --- a/configs/bf533-stamp_defconfig +++ b/configs/bf533-stamp_defconfig @@ -2,4 +2,5 @@ CONFIG_BLACKFIN=y CONFIG_TARGET_BF533_STAMP=y # CONFIG_CMD_SETEXPR is not set CONFIG_CC_OPTIMIZE_LIBS_FOR_SPEED=y +# CONFIG_REGEX is not set CONFIG_LIB_RAND=y diff --git a/configs/bf538f-ezkit_defconfig b/configs/bf538f-ezkit_defconfig index 6cb6c6bf31..668f9cb85d 100644 --- a/configs/bf538f-ezkit_defconfig +++ b/configs/bf538f-ezkit_defconfig @@ -2,4 +2,5 @@ CONFIG_BLACKFIN=y CONFIG_TARGET_BF538F_EZKIT=y # CONFIG_CMD_SETEXPR is not set CONFIG_CC_OPTIMIZE_LIBS_FOR_SPEED=y +# CONFIG_REGEX is not set CONFIG_LIB_RAND=y diff --git a/configs/chromebook_link_defconfig b/configs/chromebook_link_defconfig index 018fe91e89..9931d65dc2 100644 --- a/configs/chromebook_link_defconfig +++ b/configs/chromebook_link_defconfig @@ -3,6 +3,7 @@ CONFIG_VENDOR_GOOGLE=y CONFIG_DEFAULT_DEVICE_TREE="chromebook_link" CONFIG_TARGET_CHROMEBOOK_LINK=y CONFIG_HAVE_MRC=y +CONFIG_HAVE_VGA_BIOS=y # CONFIG_CMD_IMLS is not set # CONFIG_CMD_FLASH is not set # CONFIG_CMD_SETEXPR is not set diff --git a/configs/chromebox_panther_defconfig b/configs/chromebox_panther_defconfig index 2ac23ed97f..b3a5f28be9 100644 --- a/configs/chromebox_panther_defconfig +++ b/configs/chromebox_panther_defconfig @@ -3,6 +3,7 @@ CONFIG_VENDOR_GOOGLE=y CONFIG_DEFAULT_DEVICE_TREE="chromebox_panther" CONFIG_TARGET_CHROMEBOX_PANTHER=y CONFIG_HAVE_MRC=y +CONFIG_HAVE_VGA_BIOS=y # CONFIG_CMD_IMLS is not set # CONFIG_CMD_FLASH is not set # CONFIG_CMD_SETEXPR is not set diff --git a/configs/cm-bf548_defconfig b/configs/cm-bf548_defconfig index 949612d053..49d59dd07d 100644 --- a/configs/cm-bf548_defconfig +++ b/configs/cm-bf548_defconfig @@ -2,4 +2,5 @@ CONFIG_BLACKFIN=y CONFIG_TARGET_CM_BF548=y # CONFIG_CMD_SETEXPR is not set CONFIG_CC_OPTIMIZE_LIBS_FOR_SPEED=y +# CONFIG_REGEX is not set CONFIG_LIB_RAND=y diff --git a/configs/crownbay_defconfig b/configs/crownbay_defconfig index f3fb206b0e..17e6a72c9d 100644 --- a/configs/crownbay_defconfig +++ b/configs/crownbay_defconfig @@ -2,7 +2,12 @@ CONFIG_X86=y CONFIG_VENDOR_INTEL=y CONFIG_DEFAULT_DEVICE_TREE="crownbay" CONFIG_TARGET_CROWNBAY=y +CONFIG_SMP=y +CONFIG_MAX_CPUS=2 +CONFIG_HAVE_VGA_BIOS=y CONFIG_GENERATE_PIRQ_TABLE=y +CONFIG_GENERATE_MP_TABLE=y +CONFIG_CMD_CPU=y # CONFIG_CMD_IMLS is not set # CONFIG_CMD_FLASH is not set # CONFIG_CMD_SETEXPR is not set @@ -11,6 +16,10 @@ CONFIG_BOOTSTAGE=y CONFIG_BOOTSTAGE_REPORT=y CONFIG_CMD_BOOTSTAGE=y CONFIG_OF_CONTROL=y +CONFIG_CPU=y CONFIG_SPI_FLASH=y +CONFIG_VIDEO_VESA=y +CONFIG_FRAMEBUFFER_SET_VESA_MODE=y +CONFIG_DM_RTC=y CONFIG_USE_PRIVATE_LIBGCC=y CONFIG_SYS_VSNPRINTF=y diff --git a/configs/minnowmax_defconfig b/configs/minnowmax_defconfig index e0a9216d89..29dd44b400 100644 --- a/configs/minnowmax_defconfig +++ b/configs/minnowmax_defconfig @@ -4,6 +4,7 @@ CONFIG_DEFAULT_DEVICE_TREE="minnowmax" CONFIG_TARGET_MINNOWMAX=y CONFIG_HAVE_INTEL_ME=y CONFIG_SMP=y +CONFIG_HAVE_VGA_BIOS=y CONFIG_GENERATE_SFI_TABLE=y CONFIG_CMD_CPU=y # CONFIG_CMD_IMLS is not set @@ -15,6 +16,7 @@ CONFIG_BOOTSTAGE_REPORT=y CONFIG_CMD_BOOTSTAGE=y CONFIG_OF_CONTROL=y CONFIG_CPU=y +CONFIG_DM_PCI=y CONFIG_SPI_FLASH=y CONFIG_VIDEO_VESA=y CONFIG_FRAMEBUFFER_SET_VESA_MODE=y diff --git a/configs/stv0991_defconfig b/configs/stv0991_defconfig index 8e8ce9fb2d..3bdb1fc101 100644 --- a/configs/stv0991_defconfig +++ b/configs/stv0991_defconfig @@ -7,8 +7,8 @@ CONFIG_AUTOBOOT_KEYED=y CONFIG_AUTOBOOT_PROMPT="Hit SPACE in %d seconds to stop autoboot.\n" CONFIG_AUTOBOOT_STOP_STR=" " # CONFIG_CMD_IMLS is not set -# CONFIG_CMD_SAVEENV is not set # CONFIG_CMD_FLASH is not set # CONFIG_CMD_SETEXPR is not set CONFIG_NETDEVICES=y CONFIG_ETH_DESIGNWARE=y +CONFIG_OF_CONTROL=y diff --git a/doc/README.distro b/doc/README.distro index 0308a4c73a..9e4722a86e 100644 --- a/doc/README.distro +++ b/doc/README.distro @@ -28,7 +28,7 @@ decoupling distro install/boot logic from any knowledge of the bootloader. This model assumes that boards will load boot configuration files from a regular storage mechanism (eMMC, SD card, USB Disk, SATA disk, etc.) with -a standard partitioning scheme (MBR, GPT). Boards that cannnot support this +a standard partitioning scheme (MBR, GPT). Boards that cannot support this storage model are outside the scope of this document, and may still need board-specific installer/boot-configuration support in a distro. @@ -37,9 +37,9 @@ that contains U-Boot, and that the user has somehow installed U-Boot to this flash before running the distro installer. Even on boards that do not conform to this aspect of the model, the extent of the board-specific support in the distro installer logic would be to install a board-specific U-Boot package to -the boot partition partition during installation. This distro-supplied U-Boot -can still implement the same features as on any other board, and hence the -distro's boot configuration file generation logic can still be board-agnostic. +the boot partition during installation. This distro-supplied U-Boot can still +implement the same features as on any other board, and hence the distro's boot +configuration file generation logic can still be board-agnostic. Locating Bootable Disks ----------------------- @@ -61,7 +61,7 @@ any other bootloader) will find those boot files and execute them. This is conceptually identical to creating a grub2 configuration file on a desktop PC. -Note that in the absense of any partition that is explicitly marked bootable, +Note that in the absence of any partition that is explicitly marked bootable, U-Boot falls back to searching the first valid partition of a disk for boot configuration files. Other bootloaders are recommended to do the same, since I believe that partition table bootable flags aren't so commonly used outside @@ -238,7 +238,7 @@ kernel_addr_r: The kernel should be located within the first 128M of RAM in order for the kernel CONFIG_AUTO_ZRELADDR option to work, which is likely enabled on any distro kernel. Since the kernel will decompress itself to 0x8000 after the - start of RAM, kernel_addr_rshould not overlap that area, or the kernel will + start of RAM, kernel_addr_r should not overlap that area, or the kernel will have to copy itself somewhere else first before decompression. A size of 16MB for the kernel is likely adequate. diff --git a/doc/README.x86 b/doc/README.x86 index c19f4a03ba..5d712445df 100644 --- a/doc/README.x86 +++ b/doc/README.x86 @@ -79,7 +79,7 @@ Find the following files: * ./northbridge/intel/sandybridge/systemagent-r6.bin The 3rd one should be renamed to mrc.bin. -As for the video ROM, you can get it here [3]. +As for the video ROM, you can get it here [3] and rename it to vga.bin. Make sure all these binary blobs are put in the board directory. Now you can build U-Boot and obtain u-boot.rom: @@ -113,6 +113,10 @@ binary using any hex editor (eg: bvi). Go to the offset 0x1fcd8 of the FSP binary, change the following five bytes values from orginally E8 42 FF FF FF to B8 00 80 0B 00. +As for the video ROM, you need manually extract it from the Intel provided +BIOS for Crown Bay here [6], using the AMI MMTool [7]. Check PCI option ROM +ID 8086:4108, extract and save it as vga.bin in the board directory. + Now you can build U-Boot and obtain u-boot.rom $ make crownbay_defconfig @@ -160,6 +164,31 @@ Now you can build U-Boot and obtain u-boot.rom $ make minnowmax_defconfig $ make all +Checksums are as follows (but note that newer versions will invalidate this): + +$ md5sum -b board/intel/minnowmax/*.bin +ffda9a3b94df5b74323afb328d51e6b4 board/intel/minnowmax/descriptor.bin +69f65b9a580246291d20d08cbef9d7c5 board/intel/minnowmax/fsp.bin +894a97d371544ec21de9c3e8e1716c4b board/intel/minnowmax/me.bin +a2588537da387da592a27219d56e9962 board/intel/minnowmax/vga.bin + +The ROM image is broken up into these parts: + +Offset Description Controlling config +------------------------------------------------------------ +000000 descriptor.bin Hard-coded to 0 in ifdtool +001000 me.bin Set by the descriptor +500000 <spare> +700000 u-boot-dtb.bin CONFIG_SYS_TEXT_BASE +790000 vga.bin CONFIG_X86_OPTION_ROM_ADDR +7c0000 fsp.bin CONFIG_FSP_ADDR +7f8000 <spare> (depends on size of fsp.bin) +7fe000 Environment CONFIG_ENV_OFFSET +7ff800 U-Boot 16-bit boot CONFIG_SYS_X86_START16 + +Overall ROM image size is controlled by CONFIG_ROM_SIZE. + + Intel Galileo instructions: Only one binary blob is needed for Remote Management Unit (RMU) within Intel @@ -254,10 +283,21 @@ If you want to check both consoles, use '-serial stdio'. CPU Microcode ------------- -Modern CPUs usually require a special bit stream called microcode [6] to be +Modern CPUs usually require a special bit stream called microcode [8] to be loaded on the processor after power up in order to function properly. U-Boot has already integrated these as hex dumps in the source tree. +SMP Support +----------- +On a multicore system, U-Boot is executed on the bootstrap processor (BSP). +Additional application processors (AP) can be brought up by U-Boot. In order to +have an SMP kernel to discover all of the available processors, U-Boot needs to +prepare configuration tables which contain the multi-CPUs information before +loading the OS kernel. Currently U-Boot supports generating two types of tables +for SMP, called Simple Firmware Interface (SFI) [9] and Multi-Processor (MP) +[10] tables. The writing of these two tables are controlled by two Kconfig +options GENERATE_SFI_TABLE and GENERATE_MP_TABLE. + Driver Model ------------ x86 has been converted to use driver model for serial and GPIO. @@ -361,4 +401,8 @@ References [3] http://www.coreboot.org/~stepan/pci8086,0166.rom [4] http://www.intel.com/content/www/us/en/embedded/design-tools/evaluation-platforms/atom-e660-eg20t-development-kit.html [5] http://www.intel.com/fsp -[6] http://en.wikipedia.org/wiki/Microcode +[6] http://www.intel.com/content/www/us/en/secure/intelligent-systems/privileged/e6xx-35-b1-cmc22211.html +[7] http://www.ami.com/products/bios-uefi-tools-and-utilities/bios-uefi-utilities/ +[8] http://en.wikipedia.org/wiki/Microcode +[9] http://simplefirmware.org +[10] http://www.intel.com/design/archives/processors/pro/docs/242016.htm diff --git a/doc/device-tree-bindings/spi/spi-cadence.txt b/doc/device-tree-bindings/spi/spi-cadence.txt new file mode 100644 index 0000000000..c1e2233d7c --- /dev/null +++ b/doc/device-tree-bindings/spi/spi-cadence.txt @@ -0,0 +1,28 @@ +Cadence QSPI controller device tree bindings +-------------------------------------------- + +Required properties: +- compatible : should be "cadence,qspi". +- reg : 1.Physical base address and size of SPI registers map. + 2. Physical base address & size of NOR Flash. +- clocks : Clock phandles (see clock bindings for details). +- sram-size : spi controller sram size. +- status : enable in requried dts. + +connected flash properties +-------------------------- + +- spi-max-frequency : Max supported spi frequency. +- page-size : Flash page size. +- block-size : Flash memory block size. +- tshsl-ns : Added delay in master reference clocks (ref_clk) for + the length that the master mode chip select outputs + are de-asserted between transactions. +- tsd2d-ns : Delay in master reference clocks (ref_clk) between one + chip select being de-activated and the activation of + another. +- tchsh-ns : Delay in master reference clocks between last bit of + current transaction and de-asserting the device chip + select (n_ss_out). +- tslch-ns : Delay in master reference clocks between setting + n_ss_out low and first bit transfer diff --git a/drivers/block/Makefile b/drivers/block/Makefile index 8697da4262..f161c01c67 100644 --- a/drivers/block/Makefile +++ b/drivers/block/Makefile @@ -6,7 +6,6 @@ # obj-$(CONFIG_SCSI_AHCI) += ahci.o -obj-$(CONFIG_ATA_PIIX) += ata_piix.o obj-$(CONFIG_DWC_AHSATA) += dwc_ahsata.o obj-$(CONFIG_FSL_SATA) += fsl_sata.o obj-$(CONFIG_IDE_FTIDE020) += ftide020.o diff --git a/drivers/block/ahci.c b/drivers/block/ahci.c index 4fb846ad37..0d19dd25a3 100644 --- a/drivers/block/ahci.c +++ b/drivers/block/ahci.c @@ -43,13 +43,13 @@ u16 *ataid[AHCI_MAX_PORTS]; #define WAIT_MS_FLUSH 5000 #define WAIT_MS_LINKUP 200 -static inline u32 ahci_port_base(u32 base, u32 port) +static inline void __iomem *ahci_port_base(void __iomem *base, u32 port) { return base + 0x100 + (port * 0x80); } -static void ahci_setup_port(struct ahci_ioports *port, unsigned long base, +static void ahci_setup_port(struct ahci_ioports *port, void __iomem *base, unsigned int port_idx) { base = ahci_port_base(base, port_idx); @@ -61,7 +61,7 @@ static void ahci_setup_port(struct ahci_ioports *port, unsigned long base, #define msleep(a) udelay(a * 1000) -static void ahci_dcache_flush_range(unsigned begin, unsigned len) +static void ahci_dcache_flush_range(unsigned long begin, unsigned long len) { const unsigned long start = begin; const unsigned long end = start + len; @@ -75,7 +75,7 @@ static void ahci_dcache_flush_range(unsigned begin, unsigned len) * controller is invalidated from dcache; next access comes from * physical RAM. */ -static void ahci_dcache_invalidate_range(unsigned begin, unsigned len) +static void ahci_dcache_invalidate_range(unsigned long begin, unsigned long len) { const unsigned long start = begin; const unsigned long end = start + len; @@ -94,7 +94,7 @@ static void ahci_dcache_flush_sata_cmd(struct ahci_ioports *pp) AHCI_PORT_PRIV_DMA_SZ); } -static int waiting_for_cmd_completed(volatile u8 *offset, +static int waiting_for_cmd_completed(void __iomem *offset, int timeout_msec, u32 sign) { @@ -111,7 +111,7 @@ int __weak ahci_link_up(struct ahci_probe_ent *probe_ent, u8 port) { u32 tmp; int j = 0; - u8 *port_mmio = (u8 *)probe_ent->port[port].port_mmio; + void __iomem *port_mmio = probe_ent->port[port].port_mmio; /* * Bring up SATA link. @@ -131,7 +131,7 @@ int __weak ahci_link_up(struct ahci_probe_ent *probe_ent, u8 port) #ifdef CONFIG_SUNXI_AHCI /* The sunxi AHCI controller requires this undocumented setup */ -static void sunxi_dma_init(volatile u8 *port_mmio) +static void sunxi_dma_init(void __iomem *port_mmio) { clrsetbits_le32(port_mmio + PORT_P0DMACR, 0x0000ff00, 0x00004400); } @@ -171,10 +171,10 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent) u16 tmp16; unsigned short vendor; #endif - volatile u8 *mmio = (volatile u8 *)probe_ent->mmio_base; + void __iomem *mmio = probe_ent->mmio_base; u32 tmp, cap_save, cmd; int i, j, ret; - volatile u8 *port_mmio; + void __iomem *port_mmio; u32 port_map; debug("ahci_host_init: start\n"); @@ -215,9 +215,9 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent) for (i = 0; i < probe_ent->n_ports; i++) { if (!(port_map & (1 << i))) continue; - probe_ent->port[i].port_mmio = ahci_port_base((u32) mmio, i); + probe_ent->port[i].port_mmio = ahci_port_base(mmio, i); port_mmio = (u8 *) probe_ent->port[i].port_mmio; - ahci_setup_port(&probe_ent->port[i], (unsigned long)mmio, i); + ahci_setup_port(&probe_ent->port[i], mmio, i); /* make sure port is not active */ tmp = readl(port_mmio + PORT_CMD); @@ -299,9 +299,6 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent) writel(1 << i, mmio + HOST_IRQ_STAT); - /* set irq mask (enables interrupts) */ - writel(DEF_PORT_IRQ, port_mmio + PORT_IRQ_MASK); - /* register linkup ports */ tmp = readl(port_mmio + PORT_SCR_STAT); debug("SATA port %d status: 0x%x\n", i, tmp); @@ -329,7 +326,7 @@ static void ahci_print_info(struct ahci_probe_ent *probe_ent) pci_dev_t pdev = probe_ent->dev; u16 cc; #endif - volatile u8 *mmio = (volatile u8 *)probe_ent->mmio_base; + void __iomem *mmio = probe_ent->mmio_base; u32 vers, cap, cap2, impl, speed; const char *speed_s; const char *scc_s; @@ -462,7 +459,7 @@ static int ahci_fill_sg(u8 port, unsigned char *buf, int buf_len) for (i = 0; i < sg_count; i++) { ahci_sg->addr = - cpu_to_le32((u32) buf + i * MAX_DATA_BYTE_COUNT); + cpu_to_le32((unsigned long) buf + i * MAX_DATA_BYTE_COUNT); ahci_sg->addr_hi = 0; ahci_sg->flags_size = cpu_to_le32(0x3fffff & (buf_len < MAX_DATA_BYTE_COUNT @@ -480,8 +477,11 @@ static void ahci_fill_cmd_slot(struct ahci_ioports *pp, u32 opts) { pp->cmd_slot->opts = cpu_to_le32(opts); pp->cmd_slot->status = 0; - pp->cmd_slot->tbl_addr = cpu_to_le32(pp->cmd_tbl & 0xffffffff); - pp->cmd_slot->tbl_addr_hi = 0; + pp->cmd_slot->tbl_addr = cpu_to_le32((u32)pp->cmd_tbl & 0xffffffff); +#ifdef CONFIG_PHYS_64BIT + pp->cmd_slot->tbl_addr_hi = + cpu_to_le32((u32)(((pp->cmd_tbl) >> 16) >> 16)); +#endif } @@ -489,7 +489,7 @@ static void ahci_fill_cmd_slot(struct ahci_ioports *pp, u32 opts) static void ahci_set_feature(u8 port) { struct ahci_ioports *pp = &(probe_ent->port[port]); - volatile u8 *port_mmio = (volatile u8 *)pp->port_mmio; + void __iomem *port_mmio = pp->port_mmio; u32 cmd_fis_len = 5; /* five dwords */ u8 fis[20]; @@ -514,7 +514,7 @@ static void ahci_set_feature(u8 port) } #endif -static int wait_spinup(volatile u8 *port_mmio) +static int wait_spinup(void __iomem *port_mmio) { ulong start; u32 tf_data; @@ -532,9 +532,9 @@ static int wait_spinup(volatile u8 *port_mmio) static int ahci_port_start(u8 port) { struct ahci_ioports *pp = &(probe_ent->port[port]); - volatile u8 *port_mmio = (volatile u8 *)pp->port_mmio; + void __iomem *port_mmio = pp->port_mmio; u32 port_status; - u32 mem; + void __iomem *mem; debug("Enter start port: %d\n", port); port_status = readl(port_mmio + PORT_SCR_STAT); @@ -544,15 +544,16 @@ static int ahci_port_start(u8 port) return -1; } - mem = (u32) malloc(AHCI_PORT_PRIV_DMA_SZ + 2048); + mem = malloc(AHCI_PORT_PRIV_DMA_SZ + 2048); if (!mem) { free(pp); printf("%s: No mem for table!\n", __func__); return -ENOMEM; } - mem = (mem + 0x800) & (~0x7ff); /* Aligned to 2048-bytes */ - memset((u8 *) mem, 0, AHCI_PORT_PRIV_DMA_SZ); + /* Aligned to 2048-bytes */ + mem = memalign(2048, AHCI_PORT_PRIV_DMA_SZ); + memset(mem, 0, AHCI_PORT_PRIV_DMA_SZ); /* * First item in chunk of DMA memory: 32-slot command table, @@ -560,7 +561,7 @@ static int ahci_port_start(u8 port) */ pp->cmd_slot = (struct ahci_cmd_hdr *)(uintptr_t)virt_to_phys((void *)mem); - debug("cmd_slot = 0x%x\n", (unsigned)pp->cmd_slot); + debug("cmd_slot = %p\n", pp->cmd_slot); mem += (AHCI_CMD_SLOT_SZ + 224); /* @@ -574,13 +575,14 @@ static int ahci_port_start(u8 port) * and its scatter-gather table */ pp->cmd_tbl = virt_to_phys((void *)mem); - debug("cmd_tbl_dma = 0x%x\n", pp->cmd_tbl); + debug("cmd_tbl_dma = %lx\n", pp->cmd_tbl); mem += AHCI_CMD_TBL_HDR; pp->cmd_tbl_sg = (struct ahci_sg *)(uintptr_t)virt_to_phys((void *)mem); - writel_with_flush((u32) pp->cmd_slot, port_mmio + PORT_LST_ADDR); + writel_with_flush((unsigned long)pp->cmd_slot, + port_mmio + PORT_LST_ADDR); writel_with_flush(pp->rx_fis, port_mmio + PORT_FIS_ADDR); @@ -607,7 +609,7 @@ static int ahci_device_data_io(u8 port, u8 *fis, int fis_len, u8 *buf, { struct ahci_ioports *pp = &(probe_ent->port[port]); - volatile u8 *port_mmio = (volatile u8 *)pp->port_mmio; + void __iomem *port_mmio = pp->port_mmio; u32 opts; u32 port_status; int sg_count; @@ -632,7 +634,7 @@ static int ahci_device_data_io(u8 port, u8 *fis, int fis_len, u8 *buf, ahci_fill_cmd_slot(pp, opts); ahci_dcache_flush_sata_cmd(pp); - ahci_dcache_flush_range((unsigned)buf, (unsigned)buf_len); + ahci_dcache_flush_range((unsigned long)buf, (unsigned long)buf_len); writel_with_flush(1, port_mmio + PORT_CMD_ISSUE); @@ -642,7 +644,8 @@ static int ahci_device_data_io(u8 port, u8 *fis, int fis_len, u8 *buf, return -1; } - ahci_dcache_invalidate_range((unsigned)buf, (unsigned)buf_len); + ahci_dcache_invalidate_range((unsigned long)buf, + (unsigned long)buf_len); debug("%s: %d byte transferred.\n", __func__, pp->cmd_slot->status); return 0; @@ -1026,7 +1029,7 @@ static int ata_io_flush(u8 port) { u8 fis[20]; struct ahci_ioports *pp = &(probe_ent->port[port]); - volatile u8 *port_mmio = (volatile u8 *)pp->port_mmio; + void __iomem *port_mmio = pp->port_mmio; u32 cmd_fis_len = 5; /* five dwords */ /* Preset the FIS */ diff --git a/drivers/block/ata_piix.c b/drivers/block/ata_piix.c deleted file mode 100644 index 30426842cc..0000000000 --- a/drivers/block/ata_piix.c +++ /dev/null @@ -1,717 +0,0 @@ -/* - * Copyright (C) Procsys. All rights reserved. - * Author: Mushtaq Khan <mushtaq_k@procsys.com> - * <mushtaqk_921@yahoo.co.in> - * - * SPDX-License-Identifier: GPL-2.0+ - * - * with the reference to ata_piix driver in kernel 2.4.32 - */ - -/* - * This file contains SATA controller and SATA drive initialization functions - */ - -#include <common.h> -#include <asm/io.h> -#include <pci.h> -#include <command.h> -#include <config.h> -#include <asm/byteorder.h> -#include <part.h> -#include <ide.h> -#include <ata.h> -#include <sata.h> - -#define DEBUG_SATA 0 /* For debug prints set DEBUG_SATA to 1 */ - -#define SATA_DECL -#define DRV_DECL /* For file specific declarations */ -#include "ata_piix.h" - -/* Macros realted to PCI */ -#define PCI_SATA_BUS 0x00 -#define PCI_SATA_DEV 0x1f -#define PCI_SATA_FUNC 0x02 - -#define PCI_SATA_BASE1 0x10 -#define PCI_SATA_BASE2 0x14 -#define PCI_SATA_BASE3 0x18 -#define PCI_SATA_BASE4 0x1c -#define PCI_SATA_BASE5 0x20 -#define PCI_PMR 0x90 -#define PCI_PI 0x09 -#define PCI_PCS 0x92 -#define PCI_DMA_CTL 0x48 - -#define PORT_PRESENT (1<<0) -#define PORT_ENABLED (1<<4) - -u32 bdf; -u32 iobase1; /* Primary cmd block */ -u32 iobase2; /* Primary ctl block */ -u32 iobase3; /* Sec cmd block */ -u32 iobase4; /* sec ctl block */ -u32 iobase5; /* BMDMA*/ - -int pci_sata_init(void) -{ - u32 bus = PCI_SATA_BUS; - u32 dev = PCI_SATA_DEV; - u32 fun = PCI_SATA_FUNC; - u16 cmd = 0; - u8 lat = 0, pcibios_max_latency = 0xff; - u8 pmr; /* Port mapping reg */ - u8 pi; /* Prgming Interface reg */ - - bdf = PCI_BDF(bus, dev, fun); - pci_read_config_dword(bdf, PCI_SATA_BASE1, &iobase1); - pci_read_config_dword(bdf, PCI_SATA_BASE2, &iobase2); - pci_read_config_dword(bdf, PCI_SATA_BASE3, &iobase3); - pci_read_config_dword(bdf, PCI_SATA_BASE4, &iobase4); - pci_read_config_dword(bdf, PCI_SATA_BASE5, &iobase5); - - if ((iobase1 == 0xFFFFFFFF) || (iobase2 == 0xFFFFFFFF) || - (iobase3 == 0xFFFFFFFF) || (iobase4 == 0xFFFFFFFF) || - (iobase5 == 0xFFFFFFFF)) { - /* ERROR */ - printf("error no base addr for SATA controller\n"); - return 1; - } - - iobase1 &= 0xFFFFFFFE; - iobase2 &= 0xFFFFFFFE; - iobase3 &= 0xFFFFFFFE; - iobase4 &= 0xFFFFFFFE; - iobase5 &= 0xFFFFFFFE; - - /* check for mode */ - pci_read_config_byte(bdf, PCI_PMR, &pmr); - if (pmr > 1) { - puts("combined mode not supported\n"); - return 1; - } - - pci_read_config_byte(bdf, PCI_PI, &pi); - if ((pi & 0x05) != 0x05) { - puts("Sata is in Legacy mode\n"); - return 1; - } else - puts("sata is in Native mode\n"); - - /* MASTER CFG AND IO CFG */ - pci_read_config_word(bdf, PCI_COMMAND, &cmd); - cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_IO; - pci_write_config_word(bdf, PCI_COMMAND, cmd); - pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); - - if (lat < 16) - lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency; - else if (lat > pcibios_max_latency) - lat = pcibios_max_latency; - pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat); - - return 0; -} - -int sata_bus_probe(int port_no) -{ - int orig_mask, mask; - u16 pcs; - - mask = (PORT_PRESENT << port_no); - pci_read_config_word(bdf, PCI_PCS, &pcs); - orig_mask = (int) pcs & 0xff; - if ((orig_mask & mask) != mask) - return 0; - else - return 1; -} - -int init_sata(int dev) -{ - static int done; - u8 i, rv = 0; - - if (!done) - done = 1; - else - return 0; - - rv = pci_sata_init(); - if (rv == 1) { - puts("pci initialization failed\n"); - return 1; - } - - port[0].port_no = 0; - port[0].ioaddr.cmd_addr = iobase1; - port[0].ioaddr.altstatus_addr = port[0].ioaddr.ctl_addr = - iobase2 | ATA_PCI_CTL_OFS; - port[0].ioaddr.bmdma_addr = iobase5; - - port[1].port_no = 1; - port[1].ioaddr.cmd_addr = iobase3; - port[1].ioaddr.altstatus_addr = port[1].ioaddr.ctl_addr = - iobase4 | ATA_PCI_CTL_OFS; - port[1].ioaddr.bmdma_addr = iobase5 + 0x8; - - for (i = 0; i < CONFIG_SYS_SATA_MAXBUS; i++) - sata_port(&port[i].ioaddr); - - for (i = 0; i < CONFIG_SYS_SATA_MAXBUS; i++) { - if (!(sata_bus_probe(i))) { - port[i].port_state = 0; - printf("SATA#%d port is not present\n", i); - } else { - printf("SATA#%d port is present\n", i); - if (sata_bus_softreset(i)) - port[i].port_state = 0; - else - port[i].port_state = 1; - } - } - - for (i = 0; i < CONFIG_SYS_SATA_MAXBUS; i++) { - u8 j, devno; - - if (port[i].port_state == 0) - continue; - for (j = 0; j < CONFIG_SYS_SATA_DEVS_PER_BUS; j++) { - sata_identify(i, j); - set_Feature_cmd(i, j); - devno = i * CONFIG_SYS_SATA_DEVS_PER_BUS + j; - if ((sata_dev_desc[devno].lba > 0) && - (sata_dev_desc[devno].blksz > 0)) { - dev_print(&sata_dev_desc[devno]); - /* initialize partition type */ - init_part(&sata_dev_desc[devno]); - } - } - } - return 0; -} - -int reset_sata(int dev) -{ - return 0; -} - -static inline u8 sata_inb(unsigned long ioaddr) -{ - return inb(ioaddr); -} - -static inline void sata_outb(unsigned char val, unsigned long ioaddr) -{ - outb(val, ioaddr); -} - -static void output_data(struct sata_ioports *ioaddr, ulong * sect_buf, - int words) -{ - outsw(ioaddr->data_addr, sect_buf, words << 1); -} - -static int input_data(struct sata_ioports *ioaddr, ulong * sect_buf, int words) -{ - insw(ioaddr->data_addr, sect_buf, words << 1); - return 0; -} - -static void sata_cpy(unsigned char *dst, unsigned char *src, unsigned int len) -{ - unsigned char *end, *last; - - last = dst; - end = src + len - 1; - - /* reserve space for '\0' */ - if (len < 2) - goto OUT; - - /* skip leading white space */ - while ((*src) && (src < end) && (*src == ' ')) - ++src; - - /* copy string, omitting trailing white space */ - while ((*src) && (src < end)) { - *dst++ = *src; - if (*src++ != ' ') - last = dst; - } -OUT: - *last = '\0'; -} - -int sata_bus_softreset(int num) -{ - u8 dev = 0, status = 0, i; - - port[num].dev_mask = 0; - - for (i = 0; i < CONFIG_SYS_SATA_DEVS_PER_BUS; i++) { - if (!(sata_devchk(&port[num].ioaddr, i))) { - debug("dev_chk failed for dev#%d\n", i); - } else { - port[num].dev_mask |= (1 << i); - debug("dev_chk passed for dev#%d\n", i); - } - } - - if (!(port[num].dev_mask)) { - printf("no devices on port%d\n", num); - return 1; - } - - dev_select(&port[num].ioaddr, dev); - - port[num].ctl_reg = 0x08; /* Default value of control reg */ - sata_outb(port[num].ctl_reg, port[num].ioaddr.ctl_addr); - udelay(10); - sata_outb(port[num].ctl_reg | ATA_SRST, port[num].ioaddr.ctl_addr); - udelay(10); - sata_outb(port[num].ctl_reg, port[num].ioaddr.ctl_addr); - - /* - * spec mandates ">= 2ms" before checking status. - * We wait 150ms, because that was the magic delay used for - * ATAPI devices in Hale Landis's ATADRVR, for the period of time - * between when the ATA command register is written, and then - * status is checked. Because waiting for "a while" before - * checking status is fine, post SRST, we perform this magic - * delay here as well. - */ - mdelay(150); - status = sata_busy_wait(&port[num].ioaddr, ATA_BUSY, 300); - while ((status & ATA_BUSY)) { - mdelay(100); - status = sata_busy_wait(&port[num].ioaddr, ATA_BUSY, 3); - } - - if (status & ATA_BUSY) - printf("ata%u is slow to respond,plz be patient\n", num); - - while ((status & ATA_BUSY)) { - mdelay(100); - status = sata_chk_status(&port[num].ioaddr); - } - - if (status & ATA_BUSY) { - printf("ata%u failed to respond : bus reset failed\n", num); - return 1; - } - return 0; -} - -void sata_identify(int num, int dev) -{ - u8 cmd = 0, status = 0; - u8 devno = num * CONFIG_SYS_SATA_DEVS_PER_BUS + dev; - u16 iobuf[ATA_SECT_SIZE]; - u64 n_sectors = 0; - u8 mask = 0; - - memset(iobuf, 0, sizeof(iobuf)); - hd_driveid_t *iop = (hd_driveid_t *) iobuf; - - if (dev == 0) - mask = 0x01; - else - mask = 0x02; - - if (!(port[num].dev_mask & mask)) { - printf("dev%d is not present on port#%d\n", dev, num); - return; - } - - printf("port=%d dev=%d\n", num, dev); - - dev_select(&port[num].ioaddr, dev); - - status = 0; - cmd = ATA_CMD_IDENT; /* Device Identify Command */ - sata_outb(cmd, port[num].ioaddr.command_addr); - sata_inb(port[num].ioaddr.altstatus_addr); - udelay(10); - - status = sata_busy_wait(&port[num].ioaddr, ATA_BUSY, 1000); - if (status & ATA_ERR) { - puts("\ndevice not responding\n"); - port[num].dev_mask &= ~mask; - return; - } - - input_data(&port[num].ioaddr, (ulong *) iobuf, ATA_SECTORWORDS); - - debug("\nata%u: dev %u cfg 49:%04x 82:%04x 83:%04x 84:%04x85:%04x" - "86:%04x" "87:%04x 88:%04x\n", num, dev, iobuf[49], - iobuf[82], iobuf[83], iobuf[84], iobuf[85], iobuf[86], - iobuf[87], iobuf[88]); - - /* we require LBA and DMA support (bits 8 & 9 of word 49) */ - if (!ata_id_has_dma(iobuf) || !ata_id_has_lba(iobuf)) - debug("ata%u: no dma/lba\n", num); - ata_dump_id(iobuf); - - if (ata_id_has_lba48(iobuf)) - n_sectors = ata_id_u64(iobuf, 100); - else - n_sectors = ata_id_u32(iobuf, 60); - debug("no. of sectors %u\n", ata_id_u64(iobuf, 100)); - debug("no. of sectors %u\n", ata_id_u32(iobuf, 60)); - - if (n_sectors == 0) { - port[num].dev_mask &= ~mask; - return; - } - - sata_cpy((unsigned char *)sata_dev_desc[devno].revision, iop->fw_rev, - sizeof(sata_dev_desc[devno].revision)); - sata_cpy((unsigned char *)sata_dev_desc[devno].vendor, iop->model, - sizeof(sata_dev_desc[devno].vendor)); - sata_cpy((unsigned char *)sata_dev_desc[devno].product, iop->serial_no, - sizeof(sata_dev_desc[devno].product)); - strswab(sata_dev_desc[devno].revision); - strswab(sata_dev_desc[devno].vendor); - - if ((iop->config & 0x0080) == 0x0080) - sata_dev_desc[devno].removable = 1; - else - sata_dev_desc[devno].removable = 0; - - sata_dev_desc[devno].lba = iop->lba_capacity; - debug("lba=0x%x", sata_dev_desc[devno].lba); - -#ifdef CONFIG_LBA48 - if (iop->command_set_2 & 0x0400) { - sata_dev_desc[devno].lba48 = 1; - lba = (unsigned long long) iop->lba48_capacity[0] | - ((unsigned long long) iop->lba48_capacity[1] << 16) | - ((unsigned long long) iop->lba48_capacity[2] << 32) | - ((unsigned long long) iop->lba48_capacity[3] << 48); - } else { - sata_dev_desc[devno].lba48 = 0; - } -#endif - - /* assuming HD */ - sata_dev_desc[devno].type = DEV_TYPE_HARDDISK; - sata_dev_desc[devno].blksz = ATA_BLOCKSIZE; - sata_dev_desc[devno].log2blksz = LOG2(sata_dev_desc[devno].blksz); - sata_dev_desc[devno].lun = 0; /* just to fill something in... */ -} - -void set_Feature_cmd(int num, int dev) -{ - u8 mask = 0x00, status = 0; - - if (dev == 0) - mask = 0x01; - else - mask = 0x02; - - if (!(port[num].dev_mask & mask)) { - debug("dev%d is not present on port#%d\n", dev, num); - return; - } - - dev_select(&port[num].ioaddr, dev); - - sata_outb(SETFEATURES_XFER, port[num].ioaddr.feature_addr); - sata_outb(XFER_PIO_4, port[num].ioaddr.nsect_addr); - sata_outb(0, port[num].ioaddr.lbal_addr); - sata_outb(0, port[num].ioaddr.lbam_addr); - sata_outb(0, port[num].ioaddr.lbah_addr); - - sata_outb(ATA_DEVICE_OBS, port[num].ioaddr.device_addr); - sata_outb(ATA_CMD_SETF, port[num].ioaddr.command_addr); - - udelay(50); - mdelay(150); - - status = sata_busy_wait(&port[num].ioaddr, ATA_BUSY, 5000); - if ((status & (ATA_STAT_BUSY | ATA_STAT_ERR))) { - printf("Error : status 0x%02x\n", status); - port[num].dev_mask &= ~mask; - } -} - -void sata_port(struct sata_ioports *ioport) -{ - ioport->data_addr = ioport->cmd_addr + ATA_REG_DATA; - ioport->error_addr = ioport->cmd_addr + ATA_REG_ERR; - ioport->feature_addr = ioport->cmd_addr + ATA_REG_FEATURE; - ioport->nsect_addr = ioport->cmd_addr + ATA_REG_NSECT; - ioport->lbal_addr = ioport->cmd_addr + ATA_REG_LBAL; - ioport->lbam_addr = ioport->cmd_addr + ATA_REG_LBAM; - ioport->lbah_addr = ioport->cmd_addr + ATA_REG_LBAH; - ioport->device_addr = ioport->cmd_addr + ATA_REG_DEVICE; - ioport->status_addr = ioport->cmd_addr + ATA_REG_STATUS; - ioport->command_addr = ioport->cmd_addr + ATA_REG_CMD; -} - -int sata_devchk(struct sata_ioports *ioaddr, int dev) -{ - u8 nsect, lbal; - - dev_select(ioaddr, dev); - - sata_outb(0x55, ioaddr->nsect_addr); - sata_outb(0xaa, ioaddr->lbal_addr); - - sata_outb(0xaa, ioaddr->nsect_addr); - sata_outb(0x55, ioaddr->lbal_addr); - - sata_outb(0x55, ioaddr->nsect_addr); - sata_outb(0xaa, ioaddr->lbal_addr); - - nsect = sata_inb(ioaddr->nsect_addr); - lbal = sata_inb(ioaddr->lbal_addr); - - if ((nsect == 0x55) && (lbal == 0xaa)) - return 1; /* we found a device */ - else - return 0; /* nothing found */ -} - -void dev_select(struct sata_ioports *ioaddr, int dev) -{ - u8 tmp = 0; - - if (dev == 0) - tmp = ATA_DEVICE_OBS; - else - tmp = ATA_DEVICE_OBS | ATA_DEV1; - - sata_outb(tmp, ioaddr->device_addr); - sata_inb(ioaddr->altstatus_addr); - udelay(5); -} - -u8 sata_busy_wait(struct sata_ioports *ioaddr, int bits, unsigned int max) -{ - u8 status; - - do { - udelay(1000); - status = sata_chk_status(ioaddr); - max--; - } while ((status & bits) && (max > 0)); - - return status; -} - -u8 sata_chk_status(struct sata_ioports *ioaddr) -{ - return sata_inb(ioaddr->status_addr); -} - - -ulong sata_read(int device, ulong blknr, lbaint_t blkcnt, void *buff) -{ - ulong n = 0, *buffer = (ulong *)buff; - u8 dev = 0, num = 0, mask = 0, status = 0; - -#ifdef CONFIG_LBA48 - unsigned char lba48 = 0; - - if (blknr & 0x0000fffff0000000) { - if (!sata_dev_desc[devno].lba48) { - printf("Drive doesn't support 48-bit addressing\n"); - return 0; - } - /* more than 28 bits used, use 48bit mode */ - lba48 = 1; - } -#endif - /* Port Number */ - num = device / CONFIG_SYS_SATA_DEVS_PER_BUS; - /* dev on the port */ - if (device >= CONFIG_SYS_SATA_DEVS_PER_BUS) - dev = device - CONFIG_SYS_SATA_DEVS_PER_BUS; - else - dev = device; - - if (dev == 0) - mask = 0x01; - else - mask = 0x02; - - if (!(port[num].dev_mask & mask)) { - printf("dev%d is not present on port#%d\n", dev, num); - return 0; - } - - /* Select device */ - dev_select(&port[num].ioaddr, dev); - - status = sata_busy_wait(&port[num].ioaddr, ATA_BUSY, 500); - if (status & ATA_BUSY) { - printf("ata%u failed to respond\n", port[num].port_no); - return n; - } - while (blkcnt-- > 0) { - status = sata_busy_wait(&port[num].ioaddr, ATA_BUSY, 500); - if (status & ATA_BUSY) { - printf("ata%u failed to respond\n", 0); - return n; - } -#ifdef CONFIG_LBA48 - if (lba48) { - /* write high bits */ - sata_outb(0, port[num].ioaddr.nsect_addr); - sata_outb((blknr >> 24) & 0xFF, - port[num].ioaddr.lbal_addr); - sata_outb((blknr >> 32) & 0xFF, - port[num].ioaddr.lbam_addr); - sata_outb((blknr >> 40) & 0xFF, - port[num].ioaddr.lbah_addr); - } -#endif - sata_outb(1, port[num].ioaddr.nsect_addr); - sata_outb(((blknr) >> 0) & 0xFF, - port[num].ioaddr.lbal_addr); - sata_outb((blknr >> 8) & 0xFF, port[num].ioaddr.lbam_addr); - sata_outb((blknr >> 16) & 0xFF, port[num].ioaddr.lbah_addr); - -#ifdef CONFIG_LBA48 - if (lba48) { - sata_outb(ATA_LBA, port[num].ioaddr.device_addr); - sata_outb(ATA_CMD_READ_EXT, - port[num].ioaddr.command_addr); - } else -#endif - { - sata_outb(ATA_LBA | ((blknr >> 24) & 0xF), - port[num].ioaddr.device_addr); - sata_outb(ATA_CMD_READ, - port[num].ioaddr.command_addr); - } - - mdelay(50); - /* may take up to 4 sec */ - status = sata_busy_wait(&port[num].ioaddr, ATA_BUSY, 4000); - - if ((status & (ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR)) - != ATA_STAT_DRQ) { - u8 err = 0; - - printf("Error no DRQ dev %d blk %ld: sts 0x%02x\n", - device, (ulong) blknr, status); - err = sata_inb(port[num].ioaddr.error_addr); - printf("Error reg = 0x%x\n", err); - return n; - } - input_data(&port[num].ioaddr, buffer, ATA_SECTORWORDS); - sata_inb(port[num].ioaddr.altstatus_addr); - udelay(50); - - ++n; - ++blknr; - buffer += ATA_SECTORWORDS; - } - return n; -} - -ulong sata_write(int device, ulong blknr, lbaint_t blkcnt, const void *buff) -{ - ulong n = 0, *buffer = (ulong *)buff; - unsigned char status = 0, num = 0, dev = 0, mask = 0; - -#ifdef CONFIG_LBA48 - unsigned char lba48 = 0; - - if (blknr & 0x0000fffff0000000) { - if (!sata_dev_desc[devno].lba48) { - printf("Drive doesn't support 48-bit addressing\n"); - return 0; - } - /* more than 28 bits used, use 48bit mode */ - lba48 = 1; - } -#endif - /* Port Number */ - num = device / CONFIG_SYS_SATA_DEVS_PER_BUS; - /* dev on the Port */ - if (device >= CONFIG_SYS_SATA_DEVS_PER_BUS) - dev = device - CONFIG_SYS_SATA_DEVS_PER_BUS; - else - dev = device; - - if (dev == 0) - mask = 0x01; - else - mask = 0x02; - - /* Select device */ - dev_select(&port[num].ioaddr, dev); - - status = sata_busy_wait(&port[num].ioaddr, ATA_BUSY, 500); - if (status & ATA_BUSY) { - printf("ata%u failed to respond\n", port[num].port_no); - return n; - } - - while (blkcnt-- > 0) { - status = sata_busy_wait(&port[num].ioaddr, ATA_BUSY, 500); - if (status & ATA_BUSY) { - printf("ata%u failed to respond\n", - port[num].port_no); - return n; - } -#ifdef CONFIG_LBA48 - if (lba48) { - /* write high bits */ - sata_outb(0, port[num].ioaddr.nsect_addr); - sata_outb((blknr >> 24) & 0xFF, - port[num].ioaddr.lbal_addr); - sata_outb((blknr >> 32) & 0xFF, - port[num].ioaddr.lbam_addr); - sata_outb((blknr >> 40) & 0xFF, - port[num].ioaddr.lbah_addr); - } -#endif - sata_outb(1, port[num].ioaddr.nsect_addr); - sata_outb((blknr >> 0) & 0xFF, port[num].ioaddr.lbal_addr); - sata_outb((blknr >> 8) & 0xFF, port[num].ioaddr.lbam_addr); - sata_outb((blknr >> 16) & 0xFF, port[num].ioaddr.lbah_addr); -#ifdef CONFIG_LBA48 - if (lba48) { - sata_outb(ATA_LBA, port[num].ioaddr.device_addr); - sata_outb(ATA_CMD_WRITE_EXT, - port[num].ioaddr.command_addr); - } else -#endif - { - sata_outb(ATA_LBA | ((blknr >> 24) & 0xF), - port[num].ioaddr.device_addr); - sata_outb(ATA_CMD_WRITE, - port[num].ioaddr.command_addr); - } - - mdelay(50); - /* may take up to 4 sec */ - status = sata_busy_wait(&port[num].ioaddr, ATA_BUSY, 4000); - if ((status & (ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR)) - != ATA_STAT_DRQ) { - printf("Error no DRQ dev %d blk %ld: sts 0x%02x\n", - device, (ulong) blknr, status); - return n; - } - - output_data(&port[num].ioaddr, buffer, ATA_SECTORWORDS); - sata_inb(port[num].ioaddr.altstatus_addr); - udelay(50); - - ++n; - ++blknr; - buffer += ATA_SECTORWORDS; - } - return n; -} - -int scan_sata(int dev) -{ - return 0; -} diff --git a/drivers/block/ata_piix.h b/drivers/block/ata_piix.h deleted file mode 100644 index 6c68ea2f01..0000000000 --- a/drivers/block/ata_piix.h +++ /dev/null @@ -1,71 +0,0 @@ -#ifndef __ATA_PIIX_H__ -#define __ATA_PIIX_H__ - -struct sata_ioports { - unsigned long cmd_addr; - unsigned long data_addr; - unsigned long error_addr; - unsigned long feature_addr; - unsigned long nsect_addr; - unsigned long lbal_addr; - unsigned long lbam_addr; - unsigned long lbah_addr; - unsigned long device_addr; - unsigned long status_addr; - unsigned long command_addr; - unsigned long altstatus_addr; - unsigned long ctl_addr; - unsigned long bmdma_addr; - unsigned long scr_addr; -}; - -struct sata_port { - unsigned char port_no; /* primary=0, secondary=1 */ - struct sata_ioports ioaddr; /* ATA cmd/ctl/dma reg blks */ - unsigned char ctl_reg; - unsigned char last_ctl; - unsigned char port_state; /* 1-port is available and */ - /* 0-port is not available */ - unsigned char dev_mask; -}; - -/***********SATA LIBRARY SPECIFIC DEFINITIONS AND DECLARATIONS**************/ -#ifdef SATA_DECL /* SATA library specific declarations */ -inline void ata_dump_id(u16 *id) -{ - debug("49 = 0x%04x " - "53 = 0x%04x " - "63 = 0x%04x " - "64 = 0x%04x " - "75 = 0x%04x\n", id[49], id[53], id[63], id[64], id[75]); - debug("80 = 0x%04x " - "81 = 0x%04x " - "82 = 0x%04x " - "83 = 0x%04x " - "84 = 0x%04x\n", id[80], id[81], id[82], id[83], id[84]); - debug("88 = 0x%04x " "93 = 0x%04x\n", id[88], id[93]); -} -#endif - -#ifdef SATA_DECL /*SATA library specific declarations */ -int sata_bus_softreset(int num); -void sata_identify(int num, int dev); -void sata_port(struct sata_ioports *ioport); -void set_Feature_cmd(int num, int dev); -int sata_devchk(struct sata_ioports *ioaddr, int dev); -void dev_select(struct sata_ioports *ioaddr, int dev); -u8 sata_busy_wait(struct sata_ioports *ioaddr, int bits, unsigned int max); -u8 sata_chk_status(struct sata_ioports *ioaddr); -#endif - -/************DRIVER SPECIFIC DEFINITIONS AND DECLARATIONS**************/ - -#ifdef DRV_DECL /* Driver specific declaration */ -int init_sata(int dev); -#endif - -#ifdef DRV_DECL /* Defines Driver Specific variables */ -struct sata_port port[CONFIG_SYS_SATA_MAXBUS]; -#endif - -#endif /* __ATA_PIIX_H__ */ diff --git a/drivers/block/dwc_ahsata.c b/drivers/block/dwc_ahsata.c index cf3ef6be62..bc072f335f 100644 --- a/drivers/block/dwc_ahsata.c +++ b/drivers/block/dwc_ahsata.c @@ -80,7 +80,7 @@ struct sata_host_regs { static int is_ready; -static inline u32 ahci_port_base(u32 base, u32 port) +static inline void __iomem *ahci_port_base(void __iomem *base, u32 port) { return base + 0x100 + (port * 0x80); } @@ -167,7 +167,7 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent) for (i = 0; i < probe_ent->n_ports; i++) { probe_ent->port[i].port_mmio = - ahci_port_base((u32)host_mmio, i); + ahci_port_base(host_mmio, i); port_mmio = (struct sata_port_regs *)probe_ent->port[i].port_mmio; @@ -399,8 +399,11 @@ static void ahci_fill_cmd_slot(struct ahci_ioports *pp, u32 cmd_slot, u32 opts) memset(cmd_hdr, 0, AHCI_CMD_SLOT_SZ); cmd_hdr->opts = cpu_to_le32(opts); cmd_hdr->status = 0; - cmd_hdr->tbl_addr = cpu_to_le32(pp->cmd_tbl & 0xffffffff); - cmd_hdr->tbl_addr_hi = 0; + pp->cmd_slot->tbl_addr = cpu_to_le32((u32)pp->cmd_tbl & 0xffffffff); +#ifdef CONFIG_PHYS_64BIT + pp->cmd_slot->tbl_addr_hi = + cpu_to_le32((u32)(((pp->cmd_tbl) >> 16) >> 16)); +#endif } #define AHCI_GET_CMD_SLOT(c) ((c) ? ffs(c) : 0) @@ -520,7 +523,7 @@ static int ahci_port_start(struct ahci_probe_ent *probe_ent, * and its scatter-gather table */ pp->cmd_tbl = mem; - debug("cmd_tbl_dma = 0x%x\n", pp->cmd_tbl); + debug("cmd_tbl_dma = 0x%lx\n", pp->cmd_tbl); mem += AHCI_CMD_TBL_HDR; diff --git a/drivers/cpu/cpu-uclass.c b/drivers/cpu/cpu-uclass.c index ab18ee2ea9..7660f99ef5 100644 --- a/drivers/cpu/cpu-uclass.c +++ b/drivers/cpu/cpu-uclass.c @@ -8,9 +8,12 @@ #include <common.h> #include <cpu.h> #include <dm.h> +#include <errno.h> #include <dm/lists.h> #include <dm/root.h> +DECLARE_GLOBAL_DATA_PTR; + int cpu_get_desc(struct udevice *dev, char *buf, int size) { struct cpu_ops *ops = cpu_get_ops(dev); @@ -25,12 +28,22 @@ int cpu_get_info(struct udevice *dev, struct cpu_info *info) { struct cpu_ops *ops = cpu_get_ops(dev); - if (!ops->get_desc) + if (!ops->get_info) return -ENOSYS; return ops->get_info(dev, info); } +int cpu_get_count(struct udevice *dev) +{ + struct cpu_ops *ops = cpu_get_ops(dev); + + if (!ops->get_count) + return -ENOSYS; + + return ops->get_count(dev); +} + U_BOOT_DRIVER(cpu_bus) = { .name = "cpu_bus", .id = UCLASS_SIMPLE_BUS, diff --git a/drivers/i2c/s3c24x0_i2c.c b/drivers/i2c/s3c24x0_i2c.c index c053e84cdb..9a04e48a0f 100644 --- a/drivers/i2c/s3c24x0_i2c.c +++ b/drivers/i2c/s3c24x0_i2c.c @@ -1035,7 +1035,7 @@ static void process_nodes(const void *blob, int node_list[], int count, CONFIG_SYS_I2C_S3C24X0_SPEED); bus->node = node; bus->bus_num = i; - exynos_pinmux_config(PERIPH_ID_I2C0 + bus->id, flags); + exynos_pinmux_config(bus->id, flags); /* Mark position as used */ node_list[i] = -1; diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index 75556a332d..d89e302841 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c @@ -13,7 +13,11 @@ #include <mmc.h> #include <sdhci.h> +#if defined(CONFIG_FIXED_SDHCI_ALIGNED_BUFFER) +void *aligned_buffer = (void *)CONFIG_FIXED_SDHCI_ALIGNED_BUFFER; +#else void *aligned_buffer; +#endif static void sdhci_reset(struct sdhci_host *host, u8 mask) { @@ -133,8 +137,8 @@ static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd, int trans_bytes = 0, is_aligned = 1; u32 mask, flags, mode; unsigned int time = 0, start_addr = 0; - unsigned int retry = 10000; int mmc_dev = mmc->block_dev.dev; + unsigned start = get_timer(0); /* Timeout unit - ms */ static unsigned int cmd_timeout = CONFIG_SDHCI_CMD_DEFAULT_TIMEOUT; @@ -205,6 +209,17 @@ static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd, memcpy(aligned_buffer, data->src, trans_bytes); } +#if defined(CONFIG_FIXED_SDHCI_ALIGNED_BUFFER) + /* + * Always use this bounce-buffer when + * CONFIG_FIXED_SDHCI_ALIGNED_BUFFER is defined + */ + is_aligned = 0; + start_addr = (unsigned long)aligned_buffer; + if (data->flags != MMC_DATA_READ) + memcpy(aligned_buffer, data->src, trans_bytes); +#endif + sdhci_writel(host, start_addr, SDHCI_DMA_ADDRESS); mode |= SDHCI_TRNS_DMA; #endif @@ -222,15 +237,15 @@ static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd, flush_cache(start_addr, trans_bytes); #endif sdhci_writew(host, SDHCI_MAKE_CMD(cmd->cmdidx, flags), SDHCI_COMMAND); + start = get_timer(0); do { stat = sdhci_readl(host, SDHCI_INT_STATUS); if (stat & SDHCI_INT_ERROR) break; - if (--retry == 0) - break; - } while ((stat & mask) != mask); + } while (((stat & mask) != mask) && + (get_timer(start) < CONFIG_SDHCI_CMD_DEFAULT_TIMEOUT)); - if (retry == 0) { + if (get_timer(start) >= CONFIG_SDHCI_CMD_DEFAULT_TIMEOUT) { if (host->quirks & SDHCI_QUIRK_BROKEN_R1B) return 0; else { diff --git a/drivers/mtd/mtd_uboot.c b/drivers/mtd/mtd_uboot.c index 7197007d41..c517b9c65d 100644 --- a/drivers/mtd/mtd_uboot.c +++ b/drivers/mtd/mtd_uboot.c @@ -43,7 +43,7 @@ static int get_part(const char *partname, int *idx, loff_t *off, loff_t *size, } int mtd_arg_off(const char *arg, int *idx, loff_t *off, loff_t *size, - loff_t *maxsize, int devtype, int chipsize) + loff_t *maxsize, int devtype, uint64_t chipsize) { if (!str2off(arg, off)) return get_part(arg, idx, off, size, maxsize, devtype); @@ -59,7 +59,8 @@ int mtd_arg_off(const char *arg, int *idx, loff_t *off, loff_t *size, } int mtd_arg_off_size(int argc, char *const argv[], int *idx, loff_t *off, - loff_t *size, loff_t *maxsize, int devtype, int chipsize) + loff_t *size, loff_t *maxsize, int devtype, + uint64_t chipsize) { int ret; diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c index de87505466..5b91fe3dce 100644 --- a/drivers/pci/pci-uclass.c +++ b/drivers/pci/pci-uclass.c @@ -296,6 +296,7 @@ int pci_auto_config_devices(struct udevice *bus) !ret && dev; ret = device_find_next_child(&dev)) { struct pci_child_platdata *pplat; + struct pci_controller *ctlr_hose; pplat = dev_get_parent_platdata(dev); unsigned int max_bus; @@ -303,7 +304,10 @@ int pci_auto_config_devices(struct udevice *bus) bdf = PCI_ADD_BUS(bus->seq, pplat->devfn); debug("%s: device %s\n", __func__, dev->name); - max_bus = pciauto_config_device(hose, bdf); + + /* The root controller has the region information */ + ctlr_hose = hose->ctlr->uclass_priv; + max_bus = pciauto_config_device(ctlr_hose, bdf); sub_bus = max(sub_bus, max_bus); } debug("%s: done\n", __func__); @@ -330,7 +334,7 @@ int dm_pci_hose_probe_bus(struct pci_controller *hose, pci_dev_t bdf) sub_bus = pci_get_bus_max() + 1; debug("%s: bus = %d/%s\n", __func__, sub_bus, bus->name); - pciauto_prescan_setup_bridge(hose, bdf, bus->seq); + pciauto_prescan_setup_bridge(hose, bdf, sub_bus); ret = device_probe(bus); if (ret) { @@ -440,6 +444,7 @@ static int decode_regions(struct pci_controller *hose, const void *blob, { int pci_addr_cells, addr_cells, size_cells; int cells_per_record; + phys_addr_t addr; const u32 *prop; int len; int i; @@ -490,8 +495,11 @@ static int decode_regions(struct pci_controller *hose, const void *blob, } /* Add a region for our local memory */ - pci_set_region(hose->regions + hose->region_count++, 0, 0, - gd->ram_size, PCI_REGION_MEM | PCI_REGION_SYS_MEMORY); + addr = gd->ram_size; + if (gd->pci_ram_top && gd->pci_ram_top < addr) + addr = gd->pci_ram_top; + pci_set_region(hose->regions + hose->region_count++, 0, 0, addr, + PCI_REGION_MEM | PCI_REGION_SYS_MEMORY); return 0; } diff --git a/drivers/pci/pci_auto.c b/drivers/pci/pci_auto.c index 7c109832f6..e034ed1715 100644 --- a/drivers/pci/pci_auto.c +++ b/drivers/pci/pci_auto.c @@ -87,6 +87,8 @@ void pciauto_setup_device(struct pci_controller *hose, pci_size_t bar_size; u16 cmdstat = 0; int bar, bar_nr = 0; + u8 header_type; + int rom_addr; #ifndef CONFIG_PCI_ENUM_ONLY pci_addr_t bar_value; struct pci_region *bar_res; @@ -182,38 +184,32 @@ void pciauto_setup_device(struct pci_controller *hose, bar_nr++; } + /* Configure the expansion ROM address */ + pci_hose_read_config_byte(hose, dev, PCI_HEADER_TYPE, &header_type); + if (header_type != PCI_HEADER_TYPE_CARDBUS) { + rom_addr = (header_type == PCI_HEADER_TYPE_NORMAL) ? + PCI_ROM_ADDRESS : PCI_ROM_ADDRESS1; + pci_hose_write_config_dword(hose, dev, rom_addr, 0xfffffffe); + pci_hose_read_config_dword(hose, dev, rom_addr, &bar_response); + if (bar_response) { + bar_size = -(bar_response & ~1); + DEBUGF("PCI Autoconfig: ROM, size=%#x, ", bar_size); + if (pciauto_region_allocate(mem, bar_size, + &bar_value) == 0) { + pci_hose_write_config_dword(hose, dev, rom_addr, + bar_value); + } + cmdstat |= PCI_COMMAND_MEMORY; + DEBUGF("\n"); + } + } + pci_hose_write_config_word(hose, dev, PCI_COMMAND, cmdstat); pci_hose_write_config_byte(hose, dev, PCI_CACHE_LINE_SIZE, CONFIG_SYS_PCI_CACHE_LINE_SIZE); pci_hose_write_config_byte(hose, dev, PCI_LATENCY_TIMER, 0x80); } -int pciauto_setup_rom(struct pci_controller *hose, pci_dev_t dev) -{ - pci_addr_t bar_value; - pci_size_t bar_size; - u32 bar_response; - u16 cmdstat = 0; - - pci_hose_write_config_dword(hose, dev, PCI_ROM_ADDRESS, 0xfffffffe); - pci_hose_read_config_dword(hose, dev, PCI_ROM_ADDRESS, &bar_response); - if (!bar_response) - return -ENOENT; - - bar_size = -(bar_response & ~1); - DEBUGF("PCI Autoconfig: ROM, size=%#x, ", bar_size); - if (pciauto_region_allocate(hose->pci_mem, bar_size, &bar_value) == 0) { - pci_hose_write_config_dword(hose, dev, PCI_ROM_ADDRESS, - bar_value); - } - DEBUGF("\n"); - pci_hose_read_config_word(hose, dev, PCI_COMMAND, &cmdstat); - cmdstat |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; - pci_hose_write_config_word(hose, dev, PCI_COMMAND, cmdstat); - - return 0; -} - void pciauto_prescan_setup_bridge(struct pci_controller *hose, pci_dev_t dev, int sub_bus) { diff --git a/drivers/pci/pci_common.c b/drivers/pci/pci_common.c index b9ff23f35b..f67c9c7b2f 100644 --- a/drivers/pci/pci_common.c +++ b/drivers/pci/pci_common.c @@ -11,6 +11,7 @@ */ #include <common.h> +#include <dm.h> #include <errno.h> #include <pci.h> #include <asm/io.h> @@ -221,6 +222,11 @@ phys_addr_t pci_hose_bus_to_phys(struct pci_controller *hose, return phys_addr; } +#ifdef CONFIG_DM_PCI + /* The root controller has the region information */ + hose = hose->ctlr->uclass_priv; +#endif + /* * if PCI_REGION_MEM is set we do a two pass search with preference * on matches that don't have PCI_REGION_SYS_MEMORY set diff --git a/drivers/pci/pci_rom.c b/drivers/pci/pci_rom.c index 37450c8e31..a33efae263 100644 --- a/drivers/pci/pci_rom.c +++ b/drivers/pci/pci_rom.c @@ -31,6 +31,7 @@ #include <pci_rom.h> #include <vbe.h> #include <video_fb.h> +#include <linux/screen_info.h> #ifdef CONFIG_HAVE_ACPI_RESUME #include <asm/acpi.h> @@ -79,15 +80,10 @@ static int pci_rom_probe(pci_dev_t dev, uint class, if (vendev != mapped_vendev) debug("Device ID mapped to %#08x\n", mapped_vendev); -#ifdef CONFIG_X86_OPTION_ROM_ADDR - rom_address = CONFIG_X86_OPTION_ROM_ADDR; +#ifdef CONFIG_VGA_BIOS_ADDR + rom_address = CONFIG_VGA_BIOS_ADDR; #else - if (pciauto_setup_rom(pci_bus_to_hose(PCI_BUS(dev)), dev)) { - debug("Cannot find option ROM\n"); - return -ENOENT; - } - pci_read_config_dword(dev, PCI_ROM_ADDRESS, &rom_address); if (rom_address == 0x00000000 || rom_address == 0xffffffff) { debug("%s: rom_address=%x\n", __func__, rom_address); @@ -108,6 +104,10 @@ static int pci_rom_probe(pci_dev_t dev, uint class, if (le16_to_cpu(rom_header->signature) != PCI_ROM_HDR) { printf("Incorrect expansion ROM header signature %04x\n", le16_to_cpu(rom_header->signature)); +#ifndef CONFIG_VGA_BIOS_ADDR + /* Disable expansion ROM address decoding */ + pci_write_config_dword(dev, PCI_ROM_ADDRESS, rom_address); +#endif return -EINVAL; } @@ -203,6 +203,7 @@ int vbe_get_video_info(struct graphic_device *gdev) gdev->gdfBytesPP = vesa->bits_per_pixel / 8; switch (vesa->bits_per_pixel) { + case 32: case 24: gdev->gdfIndex = GDF_32BIT_X888RGB; break; @@ -229,6 +230,33 @@ int vbe_get_video_info(struct graphic_device *gdev) #endif } +void setup_video(struct screen_info *screen_info) +{ +#ifdef CONFIG_FRAMEBUFFER_SET_VESA_MODE + struct vesa_mode_info *vesa = &mode_info.vesa; + + screen_info->orig_video_isVGA = VIDEO_TYPE_VLFB; + + screen_info->lfb_width = vesa->x_resolution; + screen_info->lfb_height = vesa->y_resolution; + screen_info->lfb_depth = vesa->bits_per_pixel; + screen_info->lfb_linelength = vesa->bytes_per_scanline; + screen_info->lfb_base = vesa->phys_base_ptr; + screen_info->lfb_size = + ALIGN(screen_info->lfb_linelength * screen_info->lfb_height, + 65536); + screen_info->lfb_size >>= 16; + screen_info->red_size = vesa->red_mask_size; + screen_info->red_pos = vesa->red_mask_pos; + screen_info->green_size = vesa->green_mask_size; + screen_info->green_pos = vesa->green_mask_pos; + screen_info->blue_size = vesa->blue_mask_size; + screen_info->blue_pos = vesa->blue_mask_pos; + screen_info->rsvd_size = vesa->reserved_mask_size; + screen_info->rsvd_pos = vesa->reserved_mask_pos; +#endif +} + int pci_run_vga_bios(pci_dev_t dev, int (*int15_handler)(void), int exec_method) { struct pci_rom_header *rom, *ram; diff --git a/drivers/pci/pci_x86.c b/drivers/pci/pci_x86.c index 901bdcacce..89e8c119b7 100644 --- a/drivers/pci/pci_x86.c +++ b/drivers/pci/pci_x86.c @@ -7,18 +7,21 @@ #include <common.h> #include <dm.h> #include <pci.h> +#include <asm/pci.h> -static const struct dm_pci_ops x86_pci_ops = { +static const struct dm_pci_ops pci_x86_ops = { + .read_config = pci_x86_read_config, + .write_config = pci_x86_write_config, }; -static const struct udevice_id x86_pci_ids[] = { - { .compatible = "x86,pci" }, +static const struct udevice_id pci_x86_ids[] = { + { .compatible = "pci-x86" }, { } }; U_BOOT_DRIVER(pci_x86) = { .name = "pci_x86", .id = UCLASS_PCI, - .of_match = x86_pci_ids, - .ops = &x86_pci_ops, + .of_match = pci_x86_ids, + .ops = &pci_x86_ops, }; diff --git a/drivers/rtc/mc146818.c b/drivers/rtc/mc146818.c index 44857a6e41..363ade33e3 100644 --- a/drivers/rtc/mc146818.c +++ b/drivers/rtc/mc146818.c @@ -9,10 +9,9 @@ * Date & Time support for the MC146818 (PIXX4) RTC */ -/*#define DEBUG*/ - #include <common.h> #include <command.h> +#include <dm.h> #include <rtc.h> #if defined(__I386__) || defined(CONFIG_MALTA) @@ -24,9 +23,9 @@ #if defined(CONFIG_CMD_DATE) /* Set this to 1 to clear the CMOS RAM */ -#define CLEAR_CMOS 0 +#define CLEAR_CMOS 0 -#define RTC_PORT_MC146818 CONFIG_SYS_ISA_IO_BASE_ADDRESS + 0x70 +#define RTC_PORT_MC146818 CONFIG_SYS_ISA_IO_BASE_ADDRESS + 0x70 #define RTC_SECONDS 0x00 #define RTC_SECONDS_ALARM 0x01 #define RTC_MINUTES 0x02 @@ -37,10 +36,10 @@ #define RTC_DATE_OF_MONTH 0x07 #define RTC_MONTH 0x08 #define RTC_YEAR 0x09 -#define RTC_CONFIG_A 0x0A -#define RTC_CONFIG_B 0x0B -#define RTC_CONFIG_C 0x0C -#define RTC_CONFIG_D 0x0D +#define RTC_CONFIG_A 0x0a +#define RTC_CONFIG_B 0x0b +#define RTC_CONFIG_C 0x0c +#define RTC_CONFIG_D 0x0d #define RTC_REG_SIZE 0x80 #define RTC_CONFIG_A_REF_CLCK_32KHZ (1 << 5) @@ -50,89 +49,7 @@ #define RTC_CONFIG_D_VALID_RAM_AND_TIME 0x80 -/* ------------------------------------------------------------------------- */ - -int rtc_get (struct rtc_time *tmp) -{ - uchar sec, min, hour, mday, wday, mon, year; - /* here check if rtc can be accessed */ - while ((rtc_read8(RTC_CONFIG_A) & 0x80) == 0x80); - sec = rtc_read8(RTC_SECONDS); - min = rtc_read8(RTC_MINUTES); - hour = rtc_read8(RTC_HOURS); - mday = rtc_read8(RTC_DATE_OF_MONTH); - wday = rtc_read8(RTC_DAY_OF_WEEK); - mon = rtc_read8(RTC_MONTH); - year = rtc_read8(RTC_YEAR); -#ifdef RTC_DEBUG - printf ( "Get RTC year: %02x mon/cent: %02x mday: %02x wday: %02x " - "hr: %02x min: %02x sec: %02x\n", - year, mon, mday, wday, - hour, min, sec ); - printf ( "Alarms: month: %02x hour: %02x min: %02x sec: %02x\n", - rtc_read8(RTC_CONFIG_D) & 0x3F, - rtc_read8(RTC_HOURS_ALARM), - rtc_read8(RTC_MINUTES_ALARM), - rtc_read8(RTC_SECONDS_ALARM)); -#endif - tmp->tm_sec = bcd2bin (sec & 0x7F); - tmp->tm_min = bcd2bin (min & 0x7F); - tmp->tm_hour = bcd2bin (hour & 0x3F); - tmp->tm_mday = bcd2bin (mday & 0x3F); - tmp->tm_mon = bcd2bin (mon & 0x1F); - tmp->tm_year = bcd2bin (year); - tmp->tm_wday = bcd2bin (wday & 0x07); - if(tmp->tm_year<70) - tmp->tm_year+=2000; - else - tmp->tm_year+=1900; - tmp->tm_yday = 0; - tmp->tm_isdst= 0; -#ifdef RTC_DEBUG - printf ( "Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", - tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, - tmp->tm_hour, tmp->tm_min, tmp->tm_sec); -#endif - - return 0; -} - -int rtc_set (struct rtc_time *tmp) -{ -#ifdef RTC_DEBUG - printf ( "Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", - tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, - tmp->tm_hour, tmp->tm_min, tmp->tm_sec); -#endif - rtc_write8(RTC_CONFIG_B, 0x82); /* disable the RTC to update the regs */ - - rtc_write8(RTC_YEAR, bin2bcd(tmp->tm_year % 100)); - rtc_write8(RTC_MONTH, bin2bcd(tmp->tm_mon)); - rtc_write8(RTC_DAY_OF_WEEK, bin2bcd(tmp->tm_wday)); - rtc_write8(RTC_DATE_OF_MONTH, bin2bcd(tmp->tm_mday)); - rtc_write8(RTC_HOURS, bin2bcd(tmp->tm_hour)); - rtc_write8(RTC_MINUTES, bin2bcd(tmp->tm_min)); - rtc_write8(RTC_SECONDS, bin2bcd(tmp->tm_sec)); - rtc_write8(RTC_CONFIG_B, 0x02); /* enable the RTC to update the regs */ - - return 0; -} - -void rtc_reset (void) -{ - rtc_write8(RTC_CONFIG_B, 0x82); /* disable the RTC to update the regs */ - rtc_write8(RTC_CONFIG_A, 0x20); /* Normal OP */ - rtc_write8(RTC_CONFIG_B, 0x00); - rtc_write8(RTC_CONFIG_B, 0x00); - rtc_write8(RTC_CONFIG_B, 0x02); /* enable the RTC to update the regs */ -} - -/* ------------------------------------------------------------------------- */ - -/* - * use direct memory access - */ -int rtc_read8(int reg) +static int mc146818_read8(int reg) { #ifdef CONFIG_SYS_RTC_REG_BASE_ADDR return in8(CONFIG_SYS_RTC_REG_BASE_ADDR + reg); @@ -149,7 +66,7 @@ int rtc_read8(int reg) #endif } -void rtc_write8(int reg, uchar val) +static void mc146818_write8(int reg, uchar val) { #ifdef CONFIG_SYS_RTC_REG_BASE_ADDR out8(CONFIG_SYS_RTC_REG_BASE_ADDR + reg, val); @@ -165,26 +82,93 @@ void rtc_write8(int reg, uchar val) #endif } -u32 rtc_read32(int reg) +static int mc146818_get(struct rtc_time *tmp) { - u32 value = 0; - int i; + uchar sec, min, hour, mday, wday, mon, year; - for (i = 0; i < sizeof(value); i++) - value |= rtc_read8(reg + i) << (i << 3); + /* here check if rtc can be accessed */ + while ((mc146818_read8(RTC_CONFIG_A) & 0x80) == 0x80) + ; + + sec = mc146818_read8(RTC_SECONDS); + min = mc146818_read8(RTC_MINUTES); + hour = mc146818_read8(RTC_HOURS); + mday = mc146818_read8(RTC_DATE_OF_MONTH); + wday = mc146818_read8(RTC_DAY_OF_WEEK); + mon = mc146818_read8(RTC_MONTH); + year = mc146818_read8(RTC_YEAR); +#ifdef RTC_DEBUG + printf("Get RTC year: %02x mon/cent: %02x mday: %02x wday: %02x hr: %02x min: %02x sec: %02x\n", + year, mon, mday, wday, hour, min, sec); + printf("Alarms: month: %02x hour: %02x min: %02x sec: %02x\n", + mc146818_read8(RTC_CONFIG_D) & 0x3f, + mc146818_read8(RTC_HOURS_ALARM), + mc146818_read8(RTC_MINUTES_ALARM), + mc146818_read8(RTC_SECONDS_ALARM)); +#endif + tmp->tm_sec = bcd2bin(sec & 0x7f); + tmp->tm_min = bcd2bin(min & 0x7f); + tmp->tm_hour = bcd2bin(hour & 0x3f); + tmp->tm_mday = bcd2bin(mday & 0x3f); + tmp->tm_mon = bcd2bin(mon & 0x1f); + tmp->tm_year = bcd2bin(year); + tmp->tm_wday = bcd2bin(wday & 0x07); + + if (tmp->tm_year < 70) + tmp->tm_year += 2000; + else + tmp->tm_year += 1900; - return value; + tmp->tm_yday = 0; + tmp->tm_isdst = 0; +#ifdef RTC_DEBUG + printf("Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", + tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, + tmp->tm_hour, tmp->tm_min, tmp->tm_sec); +#endif + + return 0; } -void rtc_write32(int reg, u32 value) +static int mc146818_set(struct rtc_time *tmp) { - int i; +#ifdef RTC_DEBUG + printf("Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", + tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, + tmp->tm_hour, tmp->tm_min, tmp->tm_sec); +#endif + /* Disable the RTC to update the regs */ + mc146818_write8(RTC_CONFIG_B, 0x82); - for (i = 0; i < sizeof(value); i++) - rtc_write8(reg + i, (value >> (i << 3)) & 0xff); + mc146818_write8(RTC_YEAR, bin2bcd(tmp->tm_year % 100)); + mc146818_write8(RTC_MONTH, bin2bcd(tmp->tm_mon)); + mc146818_write8(RTC_DAY_OF_WEEK, bin2bcd(tmp->tm_wday)); + mc146818_write8(RTC_DATE_OF_MONTH, bin2bcd(tmp->tm_mday)); + mc146818_write8(RTC_HOURS, bin2bcd(tmp->tm_hour)); + mc146818_write8(RTC_MINUTES, bin2bcd(tmp->tm_min)); + mc146818_write8(RTC_SECONDS, bin2bcd(tmp->tm_sec)); + + /* Enable the RTC to update the regs */ + mc146818_write8(RTC_CONFIG_B, 0x02); + + return 0; } -void rtc_init(void) +static void mc146818_reset(void) +{ + /* Disable the RTC to update the regs */ + mc146818_write8(RTC_CONFIG_B, 0x82); + + /* Normal OP */ + mc146818_write8(RTC_CONFIG_A, 0x20); + mc146818_write8(RTC_CONFIG_B, 0x00); + mc146818_write8(RTC_CONFIG_B, 0x00); + + /* Enable the RTC to update the regs */ + mc146818_write8(RTC_CONFIG_B, 0x02); +} + +static void mc146818_init(void) { #if CLEAR_CMOS int i; @@ -198,14 +182,126 @@ void rtc_init(void) #endif /* Setup the real time clock */ - rtc_write8(RTC_CONFIG_B, RTC_CONFIG_B_24H); + mc146818_write8(RTC_CONFIG_B, RTC_CONFIG_B_24H); /* Setup the frequency it operates at */ - rtc_write8(RTC_CONFIG_A, RTC_CONFIG_A_REF_CLCK_32KHZ | - RTC_CONFIG_A_RATE_1024HZ); + mc146818_write8(RTC_CONFIG_A, RTC_CONFIG_A_REF_CLCK_32KHZ | + RTC_CONFIG_A_RATE_1024HZ); /* Ensure all reserved bits are 0 in register D */ - rtc_write8(RTC_CONFIG_D, RTC_CONFIG_D_VALID_RAM_AND_TIME); + mc146818_write8(RTC_CONFIG_D, RTC_CONFIG_D_VALID_RAM_AND_TIME); /* Clear any pending interrupts */ - rtc_read8(RTC_CONFIG_C); + mc146818_read8(RTC_CONFIG_C); } #endif + +#ifdef CONFIG_DM_RTC + +static int rtc_mc146818_get(struct udevice *dev, struct rtc_time *time) +{ + return mc146818_get(time); +} + +static int rtc_mc146818_set(struct udevice *dev, const struct rtc_time *time) +{ + return mc146818_set((struct rtc_time *)time); +} + +static int rtc_mc146818_reset(struct udevice *dev) +{ + mc146818_reset(); + + return 0; +} + +static int rtc_mc146818_read8(struct udevice *dev, unsigned int reg) +{ + return mc146818_read8(reg); +} + +static int rtc_mc146818_write8(struct udevice *dev, unsigned int reg, int val) +{ + mc146818_write8(reg, val); + + return 0; +} + +static int rtc_mc146818_bind(struct udevice *dev) +{ + mc146818_init(); + + return 0; +} + +static const struct rtc_ops rtc_mc146818_ops = { + .get = rtc_mc146818_get, + .set = rtc_mc146818_set, + .reset = rtc_mc146818_reset, + .read8 = rtc_mc146818_read8, + .write8 = rtc_mc146818_write8, +}; + +static const struct udevice_id rtc_mc146818_ids[] = { + { .compatible = "motorola,mc146818" }, + { } +}; + +U_BOOT_DRIVER(rtc_mc146818) = { + .name = "rtc_mc146818", + .id = UCLASS_RTC, + .of_match = rtc_mc146818_ids, + .bind = rtc_mc146818_bind, + .ops = &rtc_mc146818_ops, +}; + +#else /* !CONFIG_DM_RTC */ + +int rtc_get(struct rtc_time *tmp) +{ + return mc146818_get(tmp); +} + +int rtc_set(struct rtc_time *tmp) +{ + return mc146818_set(tmp); +} + +void rtc_reset(void) +{ + mc146818_reset(); +} + +int rtc_read8(int reg) +{ + return mc146818_read8(reg); +} + +void rtc_write8(int reg, uchar val) +{ + mc146818_write8(reg, val); +} + +u32 rtc_read32(int reg) +{ + u32 value = 0; + int i; + + for (i = 0; i < sizeof(value); i++) + value |= rtc_read8(reg + i) << (i << 3); + + return value; +} + +void rtc_write32(int reg, u32 value) +{ + int i; + + for (i = 0; i < sizeof(value); i++) + rtc_write8(reg + i, (value >> (i << 3)) & 0xff); +} + +void rtc_init(void) +{ + mc146818_init(); +} + +#endif /* CONFIG_DM_RTC */ diff --git a/drivers/spi/cadence_qspi.c b/drivers/spi/cadence_qspi.c index a75fc46e95..34a0f46a1a 100644 --- a/drivers/spi/cadence_qspi.c +++ b/drivers/spi/cadence_qspi.c @@ -309,6 +309,7 @@ static int cadence_spi_ofdata_to_platdata(struct udevice *bus) plat->tsd2d_ns = fdtdec_get_int(blob, subnode, "tsd2d-ns", 255); plat->tchsh_ns = fdtdec_get_int(blob, subnode, "tchsh-ns", 20); plat->tslch_ns = fdtdec_get_int(blob, subnode, "tslch-ns", 20); + plat->sram_size = fdtdec_get_int(blob, node, "sram-size", 128); debug("%s: regbase=%p ahbbase=%p max-frequency=%d page-size=%d\n", __func__, plat->regbase, plat->ahbbase, plat->max_hz, diff --git a/drivers/spi/cadence_qspi.h b/drivers/spi/cadence_qspi.h index c9a6142e82..98e57aa5bc 100644 --- a/drivers/spi/cadence_qspi.h +++ b/drivers/spi/cadence_qspi.h @@ -25,6 +25,7 @@ struct cadence_spi_platdata { u32 tsd2d_ns; u32 tchsh_ns; u32 tslch_ns; + u32 sram_size; }; struct cadence_spi_priv { diff --git a/drivers/spi/cadence_qspi_apb.c b/drivers/spi/cadence_qspi_apb.c index 00a115f3fb..d05340716e 100644 --- a/drivers/spi/cadence_qspi_apb.c +++ b/drivers/spi/cadence_qspi_apb.c @@ -36,12 +36,6 @@ #define CQSPI_FIFO_WIDTH (4) -/* Controller sram size in word */ -#define CQSPI_REG_SRAM_SIZE_WORD (128) -#define CQSPI_REG_SRAM_RESV_WORDS (2) -#define CQSPI_REG_SRAM_PARTITION_WR (1) -#define CQSPI_REG_SRAM_PARTITION_RD \ - (CQSPI_REG_SRAM_SIZE_WORD - CQSPI_REG_SRAM_RESV_WORDS) #define CQSPI_REG_SRAM_THRESHOLD_WORDS (50) /* Transfer mode */ @@ -206,18 +200,16 @@ static void cadence_qspi_apb_read_fifo_data(void *dest, unsigned int *dest_ptr = (unsigned int *)dest; unsigned int *src_ptr = (unsigned int *)src_ahb_addr; - while (remaining > 0) { - if (remaining >= CQSPI_FIFO_WIDTH) { - *dest_ptr = readl(src_ptr); - remaining -= CQSPI_FIFO_WIDTH; - } else { - /* dangling bytes */ - temp = readl(src_ptr); - memcpy(dest_ptr, &temp, remaining); - break; - } + while (remaining >= sizeof(dest_ptr)) { + *dest_ptr = readl(src_ptr); + remaining -= sizeof(src_ptr); dest_ptr++; } + if (remaining) { + /* dangling bytes */ + temp = readl(src_ptr); + memcpy(dest_ptr, &temp, remaining); + } return; } @@ -225,24 +217,26 @@ static void cadence_qspi_apb_read_fifo_data(void *dest, static void cadence_qspi_apb_write_fifo_data(const void *dest_ahb_addr, const void *src, unsigned int bytes) { - unsigned int temp; + unsigned int temp = 0; + int i; int remaining = bytes; unsigned int *dest_ptr = (unsigned int *)dest_ahb_addr; unsigned int *src_ptr = (unsigned int *)src; - while (remaining > 0) { - if (remaining >= CQSPI_FIFO_WIDTH) { - writel(*src_ptr, dest_ptr); - remaining -= sizeof(unsigned int); - } else { - /* dangling bytes */ - memcpy(&temp, src_ptr, remaining); - writel(temp, dest_ptr); - break; - } - src_ptr++; + while (remaining >= CQSPI_FIFO_WIDTH) { + for (i = CQSPI_FIFO_WIDTH/sizeof(src_ptr) - 1; i >= 0; i--) + writel(*(src_ptr+i), dest_ptr+i); + src_ptr += CQSPI_FIFO_WIDTH/sizeof(src_ptr); + remaining -= CQSPI_FIFO_WIDTH; + } + if (remaining) { + /* dangling bytes */ + i = remaining/sizeof(dest_ptr); + memcpy(&temp, src_ptr+i, remaining % sizeof(dest_ptr)); + writel(temp, dest_ptr+i); + for (--i; i >= 0; i--) + writel(*(src_ptr+i), dest_ptr+i); } - return; } @@ -538,6 +532,9 @@ void cadence_qspi_apb_controller_init(struct cadence_spi_platdata *plat) /* Configure the remap address register, no remap */ writel(0, plat->regbase + CQSPI_REG_REMAP); + /* Indirect mode configurations */ + writel((plat->sram_size/2), plat->regbase + CQSPI_REG_SRAMPARTITION); + /* Disable all interrupts */ writel(0, plat->regbase + CQSPI_REG_IRQMASK); @@ -700,10 +697,6 @@ int cadence_qspi_apb_indirect_read_setup(struct cadence_spi_platdata *plat, writel(((u32)plat->ahbbase & CQSPI_INDIRECTTRIGGER_ADDR_MASK), plat->regbase + CQSPI_REG_INDIRECTTRIGGER); - /* Configure SRAM partition for read. */ - writel(CQSPI_REG_SRAM_PARTITION_RD, plat->regbase + - CQSPI_REG_SRAMPARTITION); - /* Configure the opcode */ rd_reg = cmdbuf[0] << CQSPI_REG_RD_INSTR_OPCODE_LSB; @@ -801,9 +794,6 @@ int cadence_qspi_apb_indirect_write_setup(struct cadence_spi_platdata *plat, writel(((u32)plat->ahbbase & CQSPI_INDIRECTTRIGGER_ADDR_MASK), plat->regbase + CQSPI_REG_INDIRECTTRIGGER); - writel(CQSPI_REG_SRAM_PARTITION_WR, - plat->regbase + CQSPI_REG_SRAMPARTITION); - /* Configure the opcode */ reg = cmdbuf[0] << CQSPI_REG_WR_INSTR_OPCODE_LSB; writel(reg, plat->regbase + CQSPI_REG_WR_INSTR); diff --git a/drivers/spi/ich.c b/drivers/spi/ich.c index 50354fdde1..2e388e7ad9 100644 --- a/drivers/spi/ich.c +++ b/drivers/spi/ich.c @@ -40,6 +40,7 @@ struct ich_spi_priv { int status; int control; int bbar; + int bcr; uint32_t *pr; /* only for ich9 */ int speed; /* pointer to speed control */ ulong max_speed; /* Maximum bus speed in MHz */ @@ -239,6 +240,7 @@ static int ich_init_controller(struct ich_spi_platdata *plat, ctlr->speed = ctlr->control + 2; ctlr->bbar = offsetof(struct ich9_spi_regs, bbar); ctlr->preop = offsetof(struct ich9_spi_regs, preop); + ctlr->bcr = offsetof(struct ich9_spi_regs, bcr); ctlr->pr = &ich9_spi->pr[0]; ctlr->base = ich9_spi; } else { @@ -411,6 +413,7 @@ static int ich_spi_xfer(struct udevice *dev, unsigned int bitlen, const void *dout, void *din, unsigned long flags) { struct udevice *bus = dev_get_parent(dev); + struct ich_spi_platdata *plat = dev_get_platdata(bus); struct ich_spi_priv *ctlr = dev_get_priv(bus); uint16_t control; int16_t opcode_index; @@ -422,7 +425,7 @@ static int ich_spi_xfer(struct udevice *dev, unsigned int bitlen, int using_cmd = 0; int ret; - /* Ee don't support writing partial bytes. */ + /* We don't support writing partial bytes */ if (bitlen % 8) { debug("ICH SPI: Accessing partial bytes not supported\n"); return -EPROTONOSUPPORT; @@ -477,7 +480,10 @@ static int ich_spi_xfer(struct udevice *dev, unsigned int bitlen, if (ret < 0) return ret; - ich_writew(ctlr, SPIS_CDS | SPIS_FCERR, ctlr->status); + if (plat->ich_version == 7) + ich_writew(ctlr, SPIS_CDS | SPIS_FCERR, ctlr->status); + else + ich_writeb(ctlr, SPIS_CDS | SPIS_FCERR, ctlr->status); spi_setup_type(trans, using_cmd ? bytes : 0); opcode_index = spi_setup_opcode(ctlr, trans); @@ -601,7 +607,7 @@ static int ich_spi_xfer(struct udevice *dev, unsigned int bitlen, return status; if (status & SPIS_FCERR) { - debug("ICH SPI: Data transaction error\n"); + debug("ICH SPI: Data transaction error %x\n", status); return -EIO; } @@ -619,7 +625,6 @@ static int ich_spi_xfer(struct udevice *dev, unsigned int bitlen, return 0; } - /* * This uses the SPI controller from the Intel Cougar Point and Panther Point * PCH to write-protect portions of the SPI flash until reboot. The changes @@ -685,13 +690,10 @@ static int ich_spi_probe(struct udevice *bus) * v9, deassert SMM BIOS Write Protect Disable. */ if (plat->use_sbase) { - struct ich9_spi_regs *ich9_spi; - - ich9_spi = priv->base; - bios_cntl = ich_readb(priv, ich9_spi->bcr); + bios_cntl = ich_readb(priv, priv->bcr); bios_cntl &= ~(1 << 5); /* clear Enable InSMM_STS (EISS) */ bios_cntl |= 1; /* Write Protect Disable (WPD) */ - ich_writeb(priv, bios_cntl, ich9_spi->bcr); + ich_writeb(priv, bios_cntl, priv->bcr); } else { pci_read_config_byte(plat->dev, 0xdc, &bios_cntl); if (plat->ich_version == 9) diff --git a/drivers/usb/host/ehci-marvell.c b/drivers/usb/host/ehci-marvell.c index 1a5fd6eefc..03c489c014 100644 --- a/drivers/usb/host/ehci-marvell.c +++ b/drivers/usb/host/ehci-marvell.c @@ -10,6 +10,7 @@ #include <asm/io.h> #include <usb.h> #include "ehci.h" +#include <linux/mbus.h> #include <asm/arch/cpu.h> #if defined(CONFIG_KIRKWOOD) @@ -30,6 +31,40 @@ DECLARE_GLOBAL_DATA_PTR; /* * USB 2.0 Bridge Address Decoding registers setup */ +#ifdef CONFIG_ARMADA_XP + +#define MVUSB0_BASE MVEBU_USB20_BASE + +/* + * Once all the older Marvell SoC's (Orion, Kirkwood) are converted + * to the common mvebu archticture including the mbus setup, this + * will be the only function needed to configure the access windows + */ +static void usb_brg_adrdec_setup(void) +{ + const struct mbus_dram_target_info *dram; + int i; + + dram = mvebu_mbus_dram_info(); + + for (i = 0; i < 4; i++) { + wrl(USB_WINDOW_CTRL(i), 0); + wrl(USB_WINDOW_BASE(i), 0); + } + + for (i = 0; i < dram->num_cs; i++) { + const struct mbus_dram_window *cs = dram->cs + i; + + /* Write size, attributes and target id to control register */ + wrl(USB_WINDOW_CTRL(i), + ((cs->size - 1) & 0xffff0000) | (cs->mbus_attr << 8) | + (dram->mbus_dram_target_id << 4) | 1); + + /* Write base address to base register */ + wrl(USB_WINDOW_BASE(i), cs->base); + } +} +#else static void usb_brg_adrdec_setup(void) { int i; @@ -69,6 +104,7 @@ static void usb_brg_adrdec_setup(void) wrl(USB_WINDOW_BASE(i), base); } } +#endif /* * Create the appropriate control structures to manage diff --git a/drivers/video/vesa_fb.c b/drivers/video/vesa_fb.c index 47f824a726..909f8e8091 100644 --- a/drivers/video/vesa_fb.c +++ b/drivers/video/vesa_fb.c @@ -1,6 +1,5 @@ /* - * - * Vesa frame buffer driver for x86 + * VESA frame buffer driver * * Copyright (C) 2014 Google, Inc * @@ -17,16 +16,6 @@ */ GraphicDevice ctfb; -/* Devices to allow - only the last one works fully */ -struct pci_device_id vesa_video_ids[] = { - { .vendor = 0x102b, .device = 0x0525 }, - { .vendor = 0x1002, .device = 0x5159 }, - { .vendor = 0x1002, .device = 0x4752 }, - { .vendor = 0x1002, .device = 0x5452 }, - { .vendor = 0x8086, .device = 0x0f31 }, - {}, -}; - void *video_hw_init(void) { GraphicDevice *gdev = &ctfb; @@ -36,8 +25,7 @@ void *video_hw_init(void) printf("Video: "); if (vbe_get_video_info(gdev)) { - /* TODO: Should we look these up by class? */ - dev = pci_find_devices(vesa_video_ids, 0); + dev = pci_find_class(PCI_CLASS_DISPLAY_VGA << 8, 0); if (dev == -1) { printf("no card detected\n"); return NULL; diff --git a/include/ahci.h b/include/ahci.h index 6d917121c6..0bdedac187 100644 --- a/include/ahci.h +++ b/include/ahci.h @@ -135,12 +135,12 @@ struct ahci_sg { }; struct ahci_ioports { - u32 cmd_addr; - u32 scr_addr; - u32 port_mmio; + void __iomem *cmd_addr; + void __iomem *scr_addr; + void __iomem *port_mmio; struct ahci_cmd_hdr *cmd_slot; struct ahci_sg *cmd_tbl_sg; - u32 cmd_tbl; + ulong cmd_tbl; u32 rx_fis; }; diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h index 6747619b1c..db0550b67c 100644 --- a/include/asm-generic/global_data.h +++ b/include/asm-generic/global_data.h @@ -93,6 +93,7 @@ typedef struct global_data { #endif #ifdef CONFIG_PCI struct pci_controller *hose; /* PCI hose for early use */ + phys_addr_t pci_ram_top; /* top of region accessible to PCI */ #endif #ifdef CONFIG_PCI_BOOTDELAY int pcidelay_done; diff --git a/include/configs/am3517_crane.h b/include/configs/am3517_crane.h index 2f4117db29..6a0240b903 100644 --- a/include/configs/am3517_crane.h +++ b/include/configs/am3517_crane.h @@ -19,6 +19,7 @@ #define CONFIG_OMAP 1 /* in a TI OMAP core */ #define CONFIG_OMAP3_AM3517CRANE 1 /* working with CRANEBOARD */ #define CONFIG_OMAP_COMMON +#define CONFIG_SYS_GENERIC_BOARD /* Common ARM Erratas */ #define CONFIG_ARM_ERRATA_454179 #define CONFIG_ARM_ERRATA_430973 diff --git a/include/configs/am3517_evm.h b/include/configs/am3517_evm.h index e5b462174e..b90a60db0f 100644 --- a/include/configs/am3517_evm.h +++ b/include/configs/am3517_evm.h @@ -19,6 +19,7 @@ #define CONFIG_OMAP 1 /* in a TI OMAP core */ #define CONFIG_OMAP3_AM3517EVM 1 /* working with AM3517EVM */ #define CONFIG_OMAP_COMMON +#define CONFIG_SYS_GENERIC_BOARD /* Common ARM Erratas */ #define CONFIG_ARM_ERRATA_454179 #define CONFIG_ARM_ERRATA_430973 diff --git a/include/configs/baltos.h b/include/configs/baltos.h index 68bfee5e8c..cce5e4f285 100644 --- a/include/configs/baltos.h +++ b/include/configs/baltos.h @@ -16,6 +16,7 @@ #ifndef __CONFIG_BALTOS_H #define __CONFIG_BALTOS_H +#include <linux/sizes.h> #include <configs/ti_am335x_common.h> #define MACH_TYPE_TIAM335EVM 3589 /* Until the next sync */ @@ -39,8 +40,7 @@ #define CONFIG_CMD_PART /* FIT support */ -#define CONFIG_FIT -#define CONFIG_FIT_VERBOSE 1 /* enable fit_format_{error,warning}() */ +#define CONFIG_SYS_BOOTM_LEN SZ_64M #define CONFIG_OF_BOARD_SETUP /* UBI Support */ @@ -54,10 +54,11 @@ /* I2C configuration */ #undef CONFIG_SYS_OMAP24_I2C_SPEED -#define CONFIG_SYS_OMAP24_I2C_SPEED 10000 +#define CONFIG_SYS_OMAP24_I2C_SPEED 1000 +#undef CONFIG_SPL_OS_BOOT #ifdef CONFIG_NAND -#define CONFIG_SYS_NAND_U_BOOT_OFFS 0x000c0000 +#define CONFIG_SYS_NAND_U_BOOT_OFFS 0x00080000 #ifdef CONFIG_SPL_OS_BOOT #define CONFIG_CMD_SPL_NAND_OFS 0x00080000 /* os parameters */ #define CONFIG_SYS_NAND_SPL_KERNEL_OFFS 0x00200000 /* kernel offset */ @@ -80,7 +81,9 @@ "ubifsmount ubi0:kernel; " \ "ubifsload $loadaddr kernel-fit.itb;" \ "ubifsumount; " \ - "bootm ${loadaddr}#conf${board_name}\0" + "bootm ${loadaddr}#conf${board_name}; " \ + "if test $? -ne 0; then echo Using default FIT config; " \ + "bootm ${loadaddr}; fi;\0" #else #define NANDARGS "" #endif @@ -236,6 +239,7 @@ #ifdef CONFIG_NAND #define CONFIG_NAND_OMAP_GPMC +#define CONFIG_NAND_OMAP_GPMC_PREFETCH #define CONFIG_NAND_OMAP_ELM #define CONFIG_SYS_NAND_5_ADDR_CYCLE #define CONFIG_SYS_NAND_PAGE_COUNT (CONFIG_SYS_NAND_BLOCK_SIZE / \ @@ -278,9 +282,9 @@ #define CONFIG_USB_GADGET_VBUS_DRAW 2 #define CONFIG_MUSB_HOST #define CONFIG_AM335X_USB0 -#define CONFIG_AM335X_USB0_MODE MUSB_PERIPHERAL +#define CONFIG_AM335X_USB0_MODE MUSB_HOST #define CONFIG_AM335X_USB1 -#define CONFIG_AM335X_USB1_MODE MUSB_HOST +#define CONFIG_AM335X_USB1_MODE MUSB_OTG #ifdef CONFIG_MUSB_HOST #define CONFIG_CMD_USB diff --git a/include/configs/crownbay.h b/include/configs/crownbay.h index 0e1f0467c7..6cf53a3e42 100644 --- a/include/configs/crownbay.h +++ b/include/configs/crownbay.h @@ -32,15 +32,16 @@ #define CONFIG_PCI_IO_PHYS CONFIG_PCI_IO_BUS #define CONFIG_PCI_IO_SIZE 0xe000 +#define CONFIG_PCI_CONFIG_HOST_BRIDGE #define CONFIG_SYS_EARLY_PCI_INIT #define CONFIG_PCI_PNP #define CONFIG_E1000 -#define CONFIG_STD_DEVICES_SETTINGS "stdin=serial\0" \ - "stdout=serial\0" \ - "stderr=serial\0" +#define CONFIG_STD_DEVICES_SETTINGS "stdin=serial,vga,usbkbd\0" \ + "stdout=serial,vga\0" \ + "stderr=serial,vga\0" -#define CONFIG_SCSI_DEV_LIST \ +#define CONFIG_SCSI_DEV_LIST \ {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TCF_SATA} #define CONFIG_SPI_FLASH_SST @@ -55,9 +56,8 @@ #define CONFIG_PCH_GBE #define CONFIG_PHYLIB -/* Video is not supported */ -#undef CONFIG_VIDEO -#undef CONFIG_CFB_CONSOLE +/* TunnelCreek IGD support */ +#define CONFIG_VGA_AS_SINGLE_DEVICE /* Environment configuration */ #define CONFIG_ENV_SECT_SIZE 0x1000 diff --git a/include/configs/db-88f6820-gp.h b/include/configs/db-88f6820-gp.h index 24dbf6bf71..a429107a9a 100644 --- a/include/configs/db-88f6820-gp.h +++ b/include/configs/db-88f6820-gp.h @@ -29,12 +29,19 @@ #define CONFIG_CMD_CACHE #define CONFIG_CMD_DHCP #define CONFIG_CMD_ENV +#define CONFIG_CMD_EXT2 +#define CONFIG_CMD_EXT4 +#define CONFIG_CMD_FAT +#define CONFIG_CMD_FS_GENERIC #define CONFIG_CMD_I2C +#define CONFIG_CMD_MMC #define CONFIG_CMD_PING +#define CONFIG_CMD_SCSI #define CONFIG_CMD_SF #define CONFIG_CMD_SPI #define CONFIG_CMD_TFTPPUT #define CONFIG_CMD_TIME +#define CONFIG_CMD_USB /* I2C */ #define CONFIG_SYS_I2C @@ -48,6 +55,40 @@ #define CONFIG_SF_DEFAULT_MODE SPI_MODE_3 #define CONFIG_SPI_FLASH_STMICRO +/* + * SDIO/MMC Card Configuration + */ +#define CONFIG_MMC +#define CONFIG_MMC_SDMA +#define CONFIG_GENERIC_MMC +#define CONFIG_SDHCI +#define CONFIG_MV_SDHCI +#define CONFIG_SYS_MMC_BASE MVEBU_SDIO_BASE + +/* + * SATA/SCSI/AHCI configuration + */ +#define CONFIG_LIBATA +#define CONFIG_SCSI_AHCI +#define CONFIG_SCSI_AHCI_PLAT +#define CONFIG_SYS_SCSI_MAX_SCSI_ID 2 +#define CONFIG_SYS_SCSI_MAX_LUN 1 +#define CONFIG_SYS_SCSI_MAX_DEVICE (CONFIG_SYS_SCSI_MAX_SCSI_ID * \ + CONFIG_SYS_SCSI_MAX_LUN) + +/* Partition support */ +#define CONFIG_DOS_PARTITION +#define CONFIG_EFI_PARTITION + +/* Additional FS support/configuration */ +#define CONFIG_SUPPORT_VFAT + +/* USB/EHCI configuration */ +#define CONFIG_USB_EHCI +#define CONFIG_USB_STORAGE +#define CONFIG_USB_EHCI_MARVELL +#define CONFIG_EHCI_IS_TDI + /* Environment in SPI NOR flash */ #define CONFIG_ENV_IS_IN_SPI_FLASH #define CONFIG_ENV_OFFSET (1 << 20) /* 1MiB in */ diff --git a/include/configs/k2e_evm.h b/include/configs/k2e_evm.h index d83e07e242..a28ceb7064 100644 --- a/include/configs/k2e_evm.h +++ b/include/configs/k2e_evm.h @@ -20,7 +20,7 @@ #define CONFIG_EXTRA_ENV_KS2_BOARD_SETTINGS \ "addr_mon=0x0c140000\0" \ "args_ubi=setenv bootargs ${bootargs} rootfstype=ubifs " \ - "root=ubi0:rootfs rootflags=sync rw ubi.mtd=2,2048\0" \ + "root=ubi0:rootfs rootflags=sync rw ubi.mtd=ubifs,2048\0" \ "name_fdt=uImage-k2e-evm.dtb\0" \ "name_mon=skern-k2e-evm.bin\0" \ "name_ubi=k2e-evm-ubifs.ubi\0" \ diff --git a/include/configs/k2hk_evm.h b/include/configs/k2hk_evm.h index ffddf1391c..eae7721783 100644 --- a/include/configs/k2hk_evm.h +++ b/include/configs/k2hk_evm.h @@ -20,7 +20,7 @@ #define CONFIG_EXTRA_ENV_KS2_BOARD_SETTINGS \ "addr_mon=0x0c5f0000\0" \ "args_ubi=setenv bootargs ${bootargs} rootfstype=ubifs " \ - "root=ubi0:rootfs rootflags=sync rw ubi.mtd=2,2048\0" \ + "root=ubi0:rootfs rootflags=sync rw ubi.mtd=ubifs,2048\0" \ "name_fdt=uImage-k2hk-evm.dtb\0" \ "name_mon=skern-k2hk-evm.bin\0" \ "name_ubi=k2hk-evm-ubifs.ubi\0" \ diff --git a/include/configs/k2l_evm.h b/include/configs/k2l_evm.h index 805164a679..57da057925 100644 --- a/include/configs/k2l_evm.h +++ b/include/configs/k2l_evm.h @@ -20,7 +20,7 @@ #define CONFIG_EXTRA_ENV_KS2_BOARD_SETTINGS \ "addr_mon=0x0c140000\0" \ "args_ubi=setenv bootargs ${bootargs} rootfstype=ubifs " \ - "root=ubi0:rootfs rootflags=sync rw ubi.mtd=2,4096\0" \ + "root=ubi0:rootfs rootflags=sync rw ubi.mtd=ubifs,4096\0" \ "name_fdt=uImage-k2l-evm.dtb\0" \ "name_mon=skern-k2l-evm.bin\0" \ "name_ubi=k2l-evm-ubifs.ubi\0" \ diff --git a/include/configs/minnowmax.h b/include/configs/minnowmax.h index 547765d137..af36ac5caf 100644 --- a/include/configs/minnowmax.h +++ b/include/configs/minnowmax.h @@ -32,6 +32,7 @@ #define CONFIG_PCI_IO_PHYS CONFIG_PCI_IO_BUS #define CONFIG_PCI_IO_SIZE 0xe000 +#define CONFIG_PCI_CONFIG_HOST_BRIDGE #define CONFIG_SYS_EARLY_PCI_INIT #define CONFIG_PCI_PNP #define CONFIG_RTL8169 @@ -52,9 +53,6 @@ #undef CONFIG_USB_MAX_CONTROLLER_COUNT #define CONFIG_USB_MAX_CONTROLLER_COUNT 1 -#define CONFIG_X86_OPTION_ROM_FILE vga.bin -#define CONFIG_X86_OPTION_ROM_ADDR 0xfff90000 - #define VIDEO_IO_OFFSET 0 #define CONFIG_X86EMU_RAW_IO #define CONFIG_VGA_AS_SINGLE_DEVICE @@ -65,8 +63,7 @@ /* Avoid a warning in the Realtek Ethernet driver */ #define CONFIG_SYS_CACHELINE_SIZE 16 -/* Environment in SPI flash is unsupported for now */ -#undef CONFIG_ENV_IS_IN_SPI_FLASH -#define CONFIG_ENV_IS_NOWHERE +#define CONFIG_ENV_SECT_SIZE 0x1000 +#define CONFIG_ENV_OFFSET 0x007fe000 #endif /* __CONFIG_H */ diff --git a/include/configs/siemens-am33x-common.h b/include/configs/siemens-am33x-common.h index 0f325944b5..e5fd147f0d 100644 --- a/include/configs/siemens-am33x-common.h +++ b/include/configs/siemens-am33x-common.h @@ -480,7 +480,7 @@ /* * Variant 2 partition layout - * chip-size = 256MiB + * chip-size = 256MiB or 512 MiB *| name | size | address area | *------------------------------------------------------- *| spl | 128.000 KiB | 0x 0..0x 1ffff | @@ -490,23 +490,23 @@ *| u-boot | 1.875 MiB | 0x 80000..0x 25ffff | *| uboot.env0 | 512.000 KiB | 0x 260000..0x 2Dffff | *| uboot.env1 | 512.000 KiB | 0x 2E0000..0x 35ffff | - *| rootfs | 148.000 MiB | 0x 360000..0x 975ffff | - *| mtdoops | 512.000 KiB | 0x 9760000..0x 98Dffff | - *|configuration | 104.125 MiB | 0x 97E0000..0x fffffff | + *| mtdoops | 512.000 KiB | 0x 360000..0x 3dffff | + *| (256) rootfs | 252.125 MiB | 0x 3E0000..0x fffffff | + *| (512) rootfs | 508.125 MiB | 0x 3E0000..0x1fffffff | *------------------------------------------------------- */ #define MTDPARTS_DEFAULT_V2 "mtdparts=" MTDIDS_NAME_STR ":" \ - "128k(spl)," \ - "128k(spl.backup1)," \ - "128k(spl.backup2)," \ - "128k(spl.backup3)," \ - "1920k(u-boot)," \ - "512k(u-boot.env0)," \ - "512k(u-boot.env1)," \ - "148m(rootfs)," \ - "512k(mtdoops)," \ - "-(configuration)" + "128k(spl)," \ + "128k(spl.backup1)," \ + "128k(spl.backup2)," \ + "128k(spl.backup3)," \ + "1920k(u-boot)," \ + "512k(u-boot.env0)," \ + "512k(u-boot.env1)," \ + "512k(mtdoops)," \ + "-(rootfs)" + #define DFU_ALT_INFO_NAND_V2 \ "spl part 0 1;" \ @@ -516,8 +516,7 @@ "u-boot part 0 5;" \ "u-boot.env0 part 0 6;" \ "u-boot.env1 part 0 7;" \ - "rootfs partubi 0 8;" \ - "configuration partubi 0 10" + "rootfs partubi 0 9" \ #define CONFIG_ENV_SETTINGS_NAND_V2 \ "nand_active_ubi_vol=rootfs_a\0" \ @@ -534,7 +533,7 @@ "setenv nand_active_ubi_vol ${rootfs_name}_b;" \ "fi;" \ "setenv nand_root ubi0:${nand_active_ubi_vol} rw " \ - "ubi.mtd=7,2048 ubi.mtd=9,2048;" \ + "ubi.mtd=rootfs,2048;" \ "setenv bootargs ${bootargs} " \ "root=${nand_root} noinitrd ${mtdparts} " \ "rootfstype=${nand_root_fs_type} ip=${ip_method} " \ diff --git a/include/configs/stm32f429-discovery.h b/include/configs/stm32f429-discovery.h index 46869dd47f..1b4fd213cf 100644 --- a/include/configs/stm32f429-discovery.h +++ b/include/configs/stm32f429-discovery.h @@ -52,10 +52,10 @@ #define CONFIG_STM32_SERIAL /* * Configuration of the USART - * 1: TX:PA9 PX:PA10 + * 1: TX:PA9 RX:PA10 * 2: TX:PD5 RX:PD6 * 3: TX:PC10 RX:PC11 - * 6: TX:PC6 RX:PC7 + * 6: TX:PG14 RX:PG9 */ #define CONFIG_STM32_USART 1 diff --git a/include/configs/stv0991.h b/include/configs/stv0991.h index 6379fd3ab7..887f31a84d 100644 --- a/include/configs/stv0991.h +++ b/include/configs/stv0991.h @@ -23,7 +23,9 @@ #define PHYS_SDRAM_1_SIZE 0x00198000 #define CONFIG_ENV_SIZE 0x10000 -#define CONFIG_ENV_IS_IN_FLASH +#define CONFIG_ENV_IS_IN_SPI_FLASH +#define CONFIG_ENV_SECT_SIZE CONFIG_ENV_SIZE +#define CONFIG_ENV_OFFSET 0x30000 #define CONFIG_ENV_ADDR \ (PHYS_SDRAM_1_SIZE - CONFIG_ENV_SIZE) #define CONFIG_SYS_MAXARGS 16 @@ -72,7 +74,20 @@ #define CONFIG_BOOTDELAY 3 #define CONFIG_BOOTCOMMAND "go 0x40040000" -#define CONFIG_OF_SEPARATE -#define CONFIG_OF_CONTROL #define CONFIG_OF_LIBFDT + +/* ++ * QSPI support ++ */ +#ifdef CONFIG_OF_CONTROL /* QSPI is controlled via DT */ +#define CONFIG_CADENCE_QSPI +#define CONFIG_CQSPI_DECODER 0 +#define CONFIG_CQSPI_REF_CLK ((30/4)/2)*1000*1000 +#define CONFIG_CMD_SPI + +#define CONFIG_SPI_FLASH_STMICRO /* Micron/Numonyx flash */ +#define CONFIG_SPI_FLASH_WINBOND /* WINBOND */ +#define CONFIG_CMD_SF +#endif + #endif /* __CONFIG_H */ diff --git a/include/configs/x86-chromebook.h b/include/configs/x86-chromebook.h index e0e7fca9f8..408cbb1957 100644 --- a/include/configs/x86-chromebook.h +++ b/include/configs/x86-chromebook.h @@ -26,9 +26,6 @@ {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PANTHERPOINT_AHCI_MOBILE}, \ {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LYNXPOINT_AHCI} -#define CONFIG_X86_OPTION_ROM_FILE pci8086,0166.bin -#define CONFIG_X86_OPTION_ROM_ADDR 0xfff90000 - #define CONFIG_PCI_MEM_BUS 0xe0000000 #define CONFIG_PCI_MEM_PHYS CONFIG_PCI_MEM_BUS #define CONFIG_PCI_MEM_SIZE 0x10000000 diff --git a/include/cpu.h b/include/cpu.h index 34c60bcbaa..bfb0db2e2c 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -58,6 +58,14 @@ struct cpu_ops { * @return 0 if OK, -ve on error */ int (*get_info)(struct udevice *dev, struct cpu_info *info); + + /** + * get_count() - Get number of CPUs + * + * @dev: Device to check (UCLASS_CPU) + * @return CPU count if OK, -ve on error + */ + int (*get_count)(struct udevice *dev); }; #define cpu_get_ops(dev) ((struct cpu_ops *)(dev)->driver->ops) @@ -81,4 +89,12 @@ int cpu_get_desc(struct udevice *dev, char *buf, int size); */ int cpu_get_info(struct udevice *dev, struct cpu_info *info); +/** + * cpu_get_count() - Get number of CPUs + * + * @dev: Device to check (UCLASS_CPU) + * @return CPU count if OK, -ve on error + */ +int cpu_get_count(struct udevice *dev); + #endif diff --git a/include/dt-bindings/pinctrl/omap.h b/include/dt-bindings/pinctrl/omap.h index edbd250809..1dd7636a69 100644 --- a/include/dt-bindings/pinctrl/omap.h +++ b/include/dt-bindings/pinctrl/omap.h @@ -3,6 +3,8 @@ * * Copyright (C) 2009 Nokia * Copyright (C) 2009-2010 Texas Instruments + * + * SPDX-License-Identifier: GPL-2.0 */ #ifndef _DT_BINDINGS_PINCTRL_OMAP_H diff --git a/include/env_callback.h b/include/env_callback.h index ab5d42dd81..90b95b5e66 100644 --- a/include/env_callback.h +++ b/include/env_callback.h @@ -33,8 +33,10 @@ #ifdef CONFIG_REGEX #define ENV_DOT_ESCAPE "\\" +#define ETHADDR_WILDCARD "\\d?" #else #define ENV_DOT_ESCAPE +#define ETHADDR_WILDCARD #endif #ifdef CONFIG_CMD_DNS @@ -53,7 +55,7 @@ "nvlan:nvlan," \ "vlan:vlan," \ DNS_CALLBACK \ - "eth\\d?addr:ethaddr," + "eth" ETHADDR_WILDCARD "addr:ethaddr," #else #define NET_CALLBACKS #endif diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index 33669da4ed..552d4d623f 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h @@ -484,8 +484,9 @@ int add_mtd_partitions(struct mtd_info *, const struct mtd_partition *, int); int del_mtd_partitions(struct mtd_info *); int mtd_arg_off(const char *arg, int *idx, loff_t *off, loff_t *size, - loff_t *maxsize, int devtype, int chipsize); + loff_t *maxsize, int devtype, uint64_t chipsize); int mtd_arg_off_size(int argc, char *const argv[], int *idx, loff_t *off, - loff_t *size, loff_t *maxsize, int devtype, int chipsize); + loff_t *size, loff_t *maxsize, int devtype, + uint64_t chipsize); #endif #endif /* __MTD_MTD_H__ */ diff --git a/include/pci.h b/include/pci.h index 07b1e9a4f5..542e68bceb 100644 --- a/include/pci.h +++ b/include/pci.h @@ -513,6 +513,16 @@ struct pci_controller { int indirect_type; + /* + * TODO(sjg@chromium.org): With driver model we use struct + * pci_controller for both the controller and any bridge devices + * attached to it. But there is only one region list and it is in the + * top-level controller. + * + * This could be changed so that struct pci_controller is only used + * for PCI controllers and a separate UCLASS (or perhaps + * UCLASS_PCI_GENERIC) is used for bridges. + */ struct pci_region regions[MAX_PCI_REGIONS]; int region_count; @@ -712,15 +722,6 @@ void pci_write_bar32(struct pci_controller *hose, pci_dev_t dev, int barnum, u32 pci_read_bar32(struct pci_controller *hose, pci_dev_t dev, int barnum); /** - * pciauto_setup_rom() - Set up access to a device ROM - * - * @hose: PCI hose to use - * @dev: PCI device to adjust - * @return 0 if done, -ve on error - */ -int pciauto_setup_rom(struct pci_controller *hose, pci_dev_t dev); - -/** * pci_hose_find_devices() - Find devices by vendor/device ID * * @hose: PCI hose to search diff --git a/include/vbe.h b/include/vbe.h index c5deee9eca..1a86db886a 100644 --- a/include/vbe.h +++ b/include/vbe.h @@ -12,7 +12,7 @@ #define _VBE_H /* these structs are for input from and output to OF */ -struct __packed screen_info { +struct __packed vbe_screen_info { u8 display_type; /* 0=NONE, 1= analog, 2=digital */ u16 screen_width; u16 screen_height; @@ -23,7 +23,7 @@ struct __packed screen_info { u8 edid_block_zero[128]; }; -struct __packed screen_info_input { +struct __packed vbe_screen_info_input { u8 signature[4]; u16 size_reserved; u8 monitor_number; diff --git a/lib/Kconfig b/lib/Kconfig index 7ec8c98da2..c98d3997b7 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -38,6 +38,7 @@ config SYS_VSNPRINTF config REGEX bool "Enable regular expression support" + default y if NET help If this variable is defined, U-Boot is linked against the SLRE (Super Light Regular Expression) library, which adds diff --git a/net/Kconfig b/net/Kconfig index 9a9846e187..915371df91 100644 --- a/net/Kconfig +++ b/net/Kconfig @@ -4,7 +4,6 @@ menuconfig NET bool "Networking support" - select REGEX if NET diff --git a/tools/buildman/builderthread.py b/tools/buildman/builderthread.py index ce1cfddf8c..cf25bb8f1a 100644 --- a/tools/buildman/builderthread.py +++ b/tools/buildman/builderthread.py @@ -356,7 +356,7 @@ class BuilderThread(threading.Thread): # Now write the actual build output if keep_outputs: self.CopyFiles(result.out_dir, build_dir, '', ['u-boot*', '*.bin', - '*.map', '*.img', 'MLO', 'include/autoconf.mk', + '*.map', '*.img', 'MLO', 'SPL', 'include/autoconf.mk', 'spl/u-boot-spl*']) def CopyFiles(self, out_dir, build_dir, dirname, patterns): diff --git a/tools/ifdtool.c b/tools/ifdtool.c index 1d61df19f2..df166161f4 100644 --- a/tools/ifdtool.c +++ b/tools/ifdtool.c @@ -987,7 +987,7 @@ int main(int argc, char *argv[]) print_usage(argv[0]); exit(EXIT_FAILURE); } - ifile->addr = strtol(optarg, NULL, 0); + ifile->addr = strtoll(optarg, NULL, 0); ifile->type = opt == 'f' ? IF_fdt : opt == 'U' ? IF_uboot : IF_normal; if (ifile->type == IF_fdt) |