Commit d4827fcd authored by Tom Rini's avatar Tom Rini

Merge https://gitlab.denx.de/u-boot/custodians/u-boot-x86

- Various minor fixes for x86
- Switch to ACPI mode on Intel edison
- Support run-time configuration for NS16550 driver
- Update coreboot and slimbootloader serial drivers to use NS16550
run-time configuration
- ICH SPI driver fixes to hardware sequencing erase case
- Move ITSS from Apollo Lake to a more generic location
- Intel GPIO driver bug fixes
- Move to vs2017-win2016 platform build host for Azure pipelines
parents d861183d 9e0c131a
variables:
windows_vm: vs2015-win2012r2
windows_vm: vs2017-win2016
ubuntu_vm: ubuntu-18.04
ci_runner_image: trini/u-boot-gitlab-ci-runner:bionic-20200112-17Jan2020
# Add '-u 0' options for Azure pipelines, otherwise we get "permission
......
......@@ -709,6 +709,12 @@ config ROM_TABLE_SIZE
hex
default 0x10000
config HAVE_ITSS
bool "Enable ITSS"
help
Select this to include the driver for the Interrupt Timer
Subsystem (ITSS) which is found on several Intel devices.
menu "System tables"
depends on !EFI && !SYS_COREBOOT
......
......@@ -39,6 +39,7 @@ config INTEL_APOLLOLAKE
imply HAVE_X86_FIT
imply INTEL_GPIO
imply SMP
imply HAVE_ITSS
if INTEL_APOLLOLAKE
......
......@@ -19,7 +19,6 @@ obj-y += fsp_s.o
endif
obj-y += hostbridge.o
obj-y += itss.o
obj-y += lpc.o
obj-y += p2sb.o
obj-y += pch.o
......
......@@ -136,10 +136,14 @@ void arch_setup_gd(gd_t *new_gd)
/* DS: data, read/write, 4 GB, base 0 */
gdt_addr[X86_GDT_ENTRY_32BIT_DS] = GDT_ENTRY(0xc093, 0, 0xfffff);
/* FS: data, read/write, 4 GB, base (Global Data Pointer) */
/*
* FS: data, read/write, sizeof (Global Data Pointer),
* base (Global Data Pointer)
*/
new_gd->arch.gd_addr = new_gd;
gdt_addr[X86_GDT_ENTRY_32BIT_FS] = GDT_ENTRY(0xc093,
(ulong)&new_gd->arch.gd_addr, 0xfffff);
gdt_addr[X86_GDT_ENTRY_32BIT_FS] = GDT_ENTRY(0x8093,
(ulong)&new_gd->arch.gd_addr,
sizeof(new_gd->arch.gd_addr) - 1);
/* 16-bit CS: code, read/execute, 64 kB, base 0 */
gdt_addr[X86_GDT_ENTRY_16BIT_CS] = GDT_ENTRY(0x009b, 0, 0x0ffff);
......
......@@ -27,6 +27,7 @@ obj-y += microcode.o
endif
endif
obj-y += pch.o
obj-$(CONFIG_HAVE_ITSS) += itss.o
ifdef CONFIG_SPL
ifndef CONFIG_SPL_BUILD
......
// SPDX-License-Identifier: GPL-2.0
/*
* Something to do with Interrupts, but I don't know what ITSS stands for
* Interrupt Timer Subsystem
*
* Copyright (C) 2017 Intel Corporation.
* Copyright (C) 2017 Siemens AG
......@@ -15,12 +15,12 @@
#include <irq.h>
#include <p2sb.h>
#include <spl.h>
#include <asm/arch/itss.h>
#include <asm/itss.h>
struct apl_itss_platdata {
struct itss_platdata {
#if CONFIG_IS_ENABLED(OF_PLATDATA)
/* Put this first since driver model will copy the data here */
struct dtd_intel_apl_itss dtplat;
struct dtd_intel_itss dtplat;
#endif
};
......@@ -30,13 +30,13 @@ struct pmc_route {
u32 gpio;
};
struct apl_itss_priv {
struct itss_priv {
struct pmc_route *route;
uint route_count;
u32 irq_snapshot[NUM_IPC_REGS];
};
static int apl_set_polarity(struct udevice *dev, uint irq, bool active_low)
static int set_polarity(struct udevice *dev, uint irq, bool active_low)
{
u32 mask;
uint reg;
......@@ -53,9 +53,9 @@ static int apl_set_polarity(struct udevice *dev, uint irq, bool active_low)
}
#ifndef CONFIG_TPL_BUILD
static int apl_snapshot_polarities(struct udevice *dev)
static int snapshot_polarities(struct udevice *dev)
{
struct apl_itss_priv *priv = dev_get_priv(dev);
struct itss_priv *priv = dev_get_priv(dev);
const int start = GPIO_IRQ_START;
const int end = GPIO_IRQ_END;
int reg_start;
......@@ -86,9 +86,9 @@ static void show_polarities(struct udevice *dev, const char *msg)
}
}
static int apl_restore_polarities(struct udevice *dev)
static int restore_polarities(struct udevice *dev)
{
struct apl_itss_priv *priv = dev_get_priv(dev);
struct itss_priv *priv = dev_get_priv(dev);
const int start = GPIO_IRQ_START;
const int end = GPIO_IRQ_END;
int reg_start;
......@@ -132,9 +132,9 @@ static int apl_restore_polarities(struct udevice *dev)
}
#endif
static int apl_route_pmc_gpio_gpe(struct udevice *dev, uint pmc_gpe_num)
static int route_pmc_gpio_gpe(struct udevice *dev, uint pmc_gpe_num)
{
struct apl_itss_priv *priv = dev_get_priv(dev);
struct itss_priv *priv = dev_get_priv(dev);
struct pmc_route *route;
int i;
......@@ -146,14 +146,14 @@ static int apl_route_pmc_gpio_gpe(struct udevice *dev, uint pmc_gpe_num)
return -ENOENT;
}
static int apl_itss_ofdata_to_platdata(struct udevice *dev)
static int itss_ofdata_to_platdata(struct udevice *dev)
{
struct apl_itss_priv *priv = dev_get_priv(dev);
struct itss_priv *priv = dev_get_priv(dev);
int ret;
#if CONFIG_IS_ENABLED(OF_PLATDATA)
struct apl_itss_platdata *plat = dev_get_platdata(dev);
struct dtd_intel_apl_itss *dtplat = &plat->dtplat;
struct itss_platdata *plat = dev_get_platdata(dev);
struct dtd_intel_itss *dtplat = &plat->dtplat;
/*
* It would be nice to do this in the bind() method, but with
......@@ -189,26 +189,26 @@ static int apl_itss_ofdata_to_platdata(struct udevice *dev)
return 0;
}
static const struct irq_ops apl_itss_ops = {
.route_pmc_gpio_gpe = apl_route_pmc_gpio_gpe,
.set_polarity = apl_set_polarity,
static const struct irq_ops itss_ops = {
.route_pmc_gpio_gpe = route_pmc_gpio_gpe,
.set_polarity = set_polarity,
#ifndef CONFIG_TPL_BUILD
.snapshot_polarities = apl_snapshot_polarities,
.restore_polarities = apl_restore_polarities,
.snapshot_polarities = snapshot_polarities,
.restore_polarities = restore_polarities,
#endif
};
static const struct udevice_id apl_itss_ids[] = {
{ .compatible = "intel,apl-itss"},
static const struct udevice_id itss_ids[] = {
{ .compatible = "intel,itss"},
{ }
};
U_BOOT_DRIVER(apl_itss_drv) = {
.name = "intel_apl_itss",
U_BOOT_DRIVER(itss_drv) = {
.name = "intel_itss",
.id = UCLASS_IRQ,
.of_match = apl_itss_ids,
.ops = &apl_itss_ops,
.ofdata_to_platdata = apl_itss_ofdata_to_platdata,
.platdata_auto_alloc_size = sizeof(struct apl_itss_platdata),
.priv_auto_alloc_size = sizeof(struct apl_itss_priv),
.of_match = itss_ids,
.ops = &itss_ops,
.ofdata_to_platdata = itss_ofdata_to_platdata,
.platdata_auto_alloc_size = sizeof(struct itss_platdata),
.priv_auto_alloc_size = sizeof(struct itss_priv),
};
......@@ -34,18 +34,15 @@ static int slimbootloader_serial_ofdata_to_platdata(struct udevice *dev)
data->stride,
data->clk);
/*
* The data->type provides port io or mmio access type info,
* but the access type will be controlled by
* CONFIG_SYS_NS16550_PORT_MAPPED or CONFIG_SYS_NS16550_MEM32.
*
* TBD: ns16550 access type configuration in runtime.
* ex) plat->access_type = data->type
*/
plat->base = data->base;
/* ns16550 uses reg_shift, then covert stride to shift */
plat->reg_shift = data->stride >> 1;
plat->reg_width = data->stride;
plat->clock = data->clk;
plat->fcr = UART_FCR_DEFVAL;
plat->flags = 0;
if (data->type == 1)
plat->flags |= NS16550_FLAG_IO;
return 0;
}
......
......@@ -50,7 +50,7 @@ _x86boot_start:
movl %cr0, %eax
orl $(X86_CR0_NW | X86_CR0_CD), %eax
movl %eax, %cr0
wbinvd
invd
/*
* Zero the BIST (Built-In Self Test) value since we don't have it.
......
......@@ -28,7 +28,7 @@ start16:
movl %cr0, %eax
orl $(X86_CR0_NW | X86_CR0_CD), %eax
movl %eax, %cr0
wbinvd
invd
/* load the temporary Global Descriptor Table */
data32 cs lidt idt_ptr
......
......@@ -171,7 +171,7 @@
itss {
u-boot,dm-pre-reloc;
compatible = "intel,apl-itss";
compatible = "intel,itss";
intel,p2sb-port-id = <PID_ITSS>;
intel,pmc-routes = <
PMC_GPE_SW_31_0 GPIO_GPE_SW_31_0
......
......@@ -8,7 +8,6 @@
/dts-v1/;
/include/ "skeleton.dtsi"
/include/ "serial.dtsi"
/include/ "keyboard.dtsi"
/include/ "pcspkr.dtsi"
/include/ "reset.dtsi"
......@@ -40,6 +39,11 @@
u-boot,dm-pre-reloc;
};
serial: serial {
u-boot,dm-pre-reloc;
compatible = "coreboot-serial";
};
coreboot-fb {
compatible = "coreboot-fb";
};
......
......@@ -97,6 +97,25 @@ struct cb_serial {
u32 type;
u32 baseaddr;
u32 baud;
u32 regwidth;
/*
* Crystal or input frequency to the chip containing the UART.
* Provide the board specific details to allow the payload to
* initialize the chip containing the UART and make independent
* decisions as to which dividers to select and their values
* to eventually arrive at the desired console baud-rate.
*/
u32 input_hertz;
/*
* UART PCI address: bus, device, function
* 1 << 31 - Valid bit, PCI UART in use
* Bus << 20
* Device << 15
* Function << 12
*/
u32 uart_pci_addr;
};
#define CB_TAG_CONSOLE 0x0010
......
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Interrupt Timer Subsystem
*
* Copyright (C) 2017 Intel Corporation.
* Copyright 2019 Google LLC
*
......
......@@ -6,10 +6,10 @@ CONFIG_NR_DRAM_BANKS=3
CONFIG_VENDOR_INTEL=y
CONFIG_TARGET_EDISON=y
CONFIG_SMP=y
CONFIG_GENERATE_ACPI_TABLE=y
CONFIG_BOARD_EARLY_INIT_R=y
CONFIG_LAST_STAGE_INIT=y
CONFIG_HUSH_PARSER=y
# CONFIG_CMDLINE_EDITING is not set
CONFIG_CMD_CPU=y
CONFIG_CMD_ASKENV=y
CONFIG_CMD_GREPENV=y
......
......@@ -112,7 +112,7 @@ U-Boot then shuts down CAR and jumps to its relocated version.
Boot flow - U-Boot post-relocation
---------------------------------
----------------------------------
U-Boot starts up normally, running near the top of RAM. After driver model is
running, arch_fsp_init_r() is called which loads and runs the FSP-S binary.
......@@ -142,54 +142,56 @@ Performance
-----------
Bootstage is used through all phases of U-Boot to keep accurate timimgs for
boot. Use 'bootstage report' in U-Boot to see the report, e.g.:
Timer summary in microseconds (16 records):
Mark Elapsed Stage
0 0 reset
155,325 155,325 TPL
204,014 48,689 end TPL
204,385 371 SPL
738,633 534,248 end SPL
739,161 528 board_init_f
842,764 103,603 board_init_r
1,166,233 323,469 main_loop
1,166,283 50 id=175
Accumulated time:
62 fast_spi
202 dm_r
7,779 dm_spl
15,555 dm_f
208,357 fsp-m
239,847 fsp-s
292,143 mmap_spi
CPU performance is about 3500 DMIPS:
=> dhry
1000000 iterations in 161 ms: 6211180/s, 3535 DMIPS
boot. Use 'bootstage report' in U-Boot to see the report, e.g.::
Timer summary in microseconds (16 records):
Mark Elapsed Stage
0 0 reset
155,325 155,325 TPL
204,014 48,689 end TPL
204,385 371 SPL
738,633 534,248 end SPL
739,161 528 board_init_f
842,764 103,603 board_init_r
1,166,233 323,469 main_loop
1,166,283 50 id=175
Accumulated time:
62 fast_spi
202 dm_r
7,779 dm_spl
15,555 dm_f
208,357 fsp-m
239,847 fsp-s
292,143 mmap_spi
CPU performance is about 3500 DMIPS::
=> dhry
1000000 iterations in 161 ms: 6211180/s, 3535 DMIPS
Partial memory map
------------------
ffffffff Top of ROM (and last byte of 32-bit address space)
ffff8000 TPL loaded here (from IFWI)
ff000000 Bottom of ROM
fefc000 Top of CAR region
fef96000 Stack for FSP-M
fef40000 59000 FSP-M
fef11000 SPL loaded here
fef10000 CONFIG_BLOBLIST_ADDR
fef10000 Stack top in TPL, SPL and U-Boot before relocation
fef00000 1000 CONFIG_BOOTSTAGE_STASH_ADDR
fef00000 Base of CAR region
f0000 CONFIG_ROM_TABLE_ADDR
120000 BSS (defined in u-boot-spl.lds)
200000 FSP-S (which is run after U-Boot is relocated)
1110000 CONFIG_SYS_TEXT_BASE
::
ffffffff Top of ROM (and last byte of 32-bit address space)
ffff8000 TPL loaded here (from IFWI)
ff000000 Bottom of ROM
fefc000 Top of CAR region
fef96000 Stack for FSP-M
fef40000 59000 FSP-M
fef11000 SPL loaded here
fef10000 CONFIG_BLOBLIST_ADDR
fef10000 Stack top in TPL, SPL and U-Boot before relocation
fef00000 1000 CONFIG_BOOTSTAGE_STASH_ADDR
fef00000 Base of CAR region
f0000 CONFIG_ROM_TABLE_ADDR
120000 BSS (defined in u-boot-spl.lds)
200000 FSP-S (which is run after U-Boot is relocated)
1110000 CONFIG_SYS_TEXT_BASE
Supported peripherals
......
......@@ -111,35 +111,16 @@ Download it from http://downloads.yoctoproject.org/releases/yocto/yocto-2.0/mach
Build Instruction for Slim Bootloader for LeafHill (APL) target
---------------------------------------------------------------
LeafHill is using PCI UART2 device as a serial port.
For MEM32 serial port, CONFIG_SYS_NS16550_MEM32 needs to be enabled in U-Boot.
Prepare U-Boot and Slim Bootloader as described at the beginning of this page.
Also, the PayloadId needs to be set for APL board.
1. Enable CONFIG_SYS_NS16550_MEM32 in U-Boot::
$ vi include/configs/slimbootloader.h
+#define CONFIG_SYS_NS16550_MEM32
#ifdef CONFIG_SYS_NS16550_MEM3
2. Build U-Boot::
$ make disclean
$ make slimbootloader_defconfig
$ make all
3. Copy u-boot-dtb.bin to Slim Bootloader.
Slim Bootloader looks for a payload from the specific location.
Copy the build u-boot-dtb.bin to the expected location::
$ mkdir -p <Slim Bootloader Dir>/PayloadPkg/PayloadBins/
$ cp <U-Boot Dir>/u-boot-dtb.bin <Slim Bootloader Dir>/PayloadPkg/PayloadBins/u-boot-dtb.bin
4. Update PayloadId. Let's use 'U-BT' as an example::
1. Update PayloadId. Let's use 'U-BT' as an example::
$ vi Platform/ApollolakeBoardPkg/CfgData/CfgData_Int_LeafHill.dlt
-GEN_CFG_DATA.PayloadId | 'AUTO
+GEN_CFG_DATA.PayloadId | 'U-BT'
5. Update payload text base.
2. Update payload text base.
* PAYLOAD_EXE_BASE must be the same as U-Boot CONFIG_SYS_TEXT_BASE
in board/intel/slimbootloader/Kconfig.
......@@ -149,18 +130,18 @@ For MEM32 serial port, CONFIG_SYS_NS16550_MEM32 needs to be enabled in U-Boot.
+ self.PAYLOAD_LOAD_HIGH = 0
+ self.PAYLOAD_EXE_BASE = 0x00100000
6. Build APL target. Make sure u-boot-dtb.bin and U-BT PayloadId
3. Build APL target. Make sure u-boot-dtb.bin and U-BT PayloadId
in build command. The output is Outputs/apl/Stitch_Components.zip::
$ python BuildLoader.py build apl -p "OsLoader.efi:LLDR:Lz4;u-boot-dtb.bin:U-BT:Lzma"
7. Stitch IFWI.
4. Stitch IFWI.
Refer to Apollolake_ page in Slim Bootloader document site::
$ python Platform/ApollolakeBoardPkg/Script/StitchLoader.py -i <Existing IFWI> -s Outputs/apl/Stitch_Components.zip -o <Output IFWI>
8. Flash IFWI.
5. Flash IFWI.
Use DediProg to flash IFWI. You should reach at U-Boot serial console.
......@@ -175,7 +156,7 @@ Build Instruction to use ELF U-Boot
2. Build U-Boot::
$ make disclean
$ make distclean
$ make slimbootloader_defconfig
$ make all
$ strip u-boot (removing symbol for reduced size)
......
......@@ -39,9 +39,9 @@ static int intel_gpio_direction_output(struct udevice *dev, uint offset,
struct udevice *pinctrl = dev_get_parent(dev);
uint config_offset = intel_pinctrl_get_config_reg_addr(pinctrl, offset);
pcr_clrsetbits32(dev, config_offset,
pcr_clrsetbits32(pinctrl, config_offset,
PAD_CFG0_MODE_MASK | PAD_CFG0_RX_STATE |
PAD_CFG0_TX_DISABLE,
PAD_CFG0_TX_DISABLE | PAD_CFG0_TX_STATE,
PAD_CFG0_MODE_GPIO | PAD_CFG0_RX_DISABLE |
(value ? PAD_CFG0_TX_STATE : 0));
......@@ -59,9 +59,9 @@ static int intel_gpio_get_value(struct udevice *dev, uint offset)
if (!mode) {
rx_tx = reg & (PAD_CFG0_TX_DISABLE | PAD_CFG0_RX_DISABLE);
if (rx_tx == PAD_CFG0_TX_DISABLE)
return mode & PAD_CFG0_RX_STATE_BIT ? 1 : 0;
return reg & PAD_CFG0_RX_STATE ? 1 : 0;
else if (rx_tx == PAD_CFG0_RX_DISABLE)
return mode & PAD_CFG0_TX_STATE_BIT ? 1 : 0;
return reg & PAD_CFG0_TX_STATE ? 1 : 0;
}
return 0;
......@@ -72,7 +72,7 @@ static int intel_gpio_set_value(struct udevice *dev, unsigned offset, int value)
struct udevice *pinctrl = dev_get_parent(dev);
uint config_offset = intel_pinctrl_get_config_reg_addr(pinctrl, offset);
pcr_clrsetbits32(dev, config_offset, PAD_CFG0_TX_STATE,
pcr_clrsetbits32(pinctrl, config_offset, PAD_CFG0_TX_STATE,
value ? PAD_CFG0_TX_STATE : 0);
return 0;
......
......@@ -25,7 +25,7 @@
#include <asm/intel_pinctrl.h>
#include <asm/intel_pinctrl_defs.h>
#include <asm/arch/gpio.h>
#include <asm/arch/itss.h>
#include <asm/itss.h>
#include <dm/device-internal.h>
#include <dt-bindings/gpio/gpio.h>
......
......@@ -542,6 +542,17 @@ config BCM6345_SERIAL
help
Select this to enable UART on BCM6345 SoCs.
config COREBOOT_SERIAL
bool "Coreboot UART support"
depends on DM_SERIAL
default y if SYS_COREBOOT
select SYS_NS16550
help
Select this to enable a ns16550-style UART where the platform data
comes from the coreboot 'sysinfo' tables. This allows U-Boot to have
a serial console on any platform without needing to change the
device tree, etc.
config FSL_LINFLEXUART
bool "Freescale Linflex UART support"
depends on DM_SERIAL
......@@ -601,6 +612,27 @@ config SYS_NS16550
be used. It can be a constant or a function to get clock, eg,
get_serial_clock().
config NS16550_DYNAMIC
bool "Allow NS16550 to be configured at runtime"
default y if SYS_COREBOOT || SYS_SLIMBOOTLOADER
help
Enable this option to allow device-tree control of the driver.
Normally this driver is controlled by the following options:
CONFIG_SYS_NS16550_PORT_MAPPED - indicates that port I/O is used for
access. If not enabled, then the UART is memory-mapped.
CONFIG_SYS_NS16550_MEM32 - if memory-mapped, indicates that 32-bit
access should be used (instead of 8-bit)
CONFIG_SYS_NS16550_REG_SIZE - indicates register width and also
endianness. If positive, big-endian access is used. If negative,
little-endian is used.
It is not a good practice for a driver to be statically configured,
since it prevents the same driver being used for different types of
UARTs in a system. This option avoids this problem at the cost of a
slightly increased code size.
config INTEL_MID_SERIAL
bool "Intel MID platform UART support"
depends on DM_SERIAL && OF_CONTROL
......
......@@ -35,6 +35,7 @@ obj-$(CONFIG_AR933X_UART) += serial_ar933x.o
obj-$(CONFIG_ARM_DCC) += arm_dcc.o
obj-$(CONFIG_ATMEL_USART) += atmel_usart.o
obj-$(CONFIG_BCM6345_SERIAL) += serial_bcm6345.o
obj-$(CONFIG_COREBOOT_SERIAL) += serial_coreboot.o
obj-$(CONFIG_EFI_APP) += serial_efi.o
obj-$(CONFIG_LPC32XX_HSUART) += lpc32xx_hsuart.o
obj-$(CONFIG_MCFUART) += mcfuart.o
......
......@@ -93,19 +93,79 @@ static inline int serial_in_shift(void *addr, int shift)
#define CONFIG_SYS_NS16550_CLK 0
#endif
/*
* Use this #ifdef for now since many platforms don't define in(), out(),
* out_le32(), etc. but we don't have #defines to indicate this.
*
* TODO(sjg@chromium.org): Add CONFIG options to indicate what I/O is available
* on a platform
*/
#ifdef CONFIG_NS16550_DYNAMIC
static void serial_out_dynamic(struct ns16550_platdata *plat, u8 *addr,
int value)
{
if (plat->flags & NS16550_FLAG_IO) {
outb(value, addr);
} else if (plat->reg_width == 4) {
if (plat->flags & NS16550_FLAG_ENDIAN) {
if (plat->flags & NS16550_FLAG_BE)
out_be32(addr, value);
else
out_le32(addr, value);
} else {
writel(value, addr);
}