summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.azure-pipelines.yml2
-rw-r--r--arch/x86/Kconfig6
-rw-r--r--arch/x86/cpu/apollolake/Kconfig1
-rw-r--r--arch/x86/cpu/apollolake/Makefile1
-rw-r--r--arch/x86/cpu/i386/cpu.c10
-rw-r--r--arch/x86/cpu/intel_common/Makefile1
-rw-r--r--arch/x86/cpu/intel_common/itss.c (renamed from arch/x86/cpu/apollolake/itss.c)60
-rw-r--r--arch/x86/cpu/slimbootloader/serial.c13
-rw-r--r--arch/x86/cpu/start.S2
-rw-r--r--arch/x86/cpu/start16.S2
-rw-r--r--arch/x86/dts/chromebook_coral.dts2
-rw-r--r--arch/x86/dts/coreboot.dts6
-rw-r--r--arch/x86/include/asm/coreboot_tables.h19
-rw-r--r--arch/x86/include/asm/itss.h (renamed from arch/x86/include/asm/arch-apollolake/itss.h)2
-rw-r--r--configs/edison_defconfig2
-rw-r--r--doc/board/google/chromebook_coral.rst90
-rw-r--r--doc/board/intel/slimbootloader.rst35
-rw-r--r--drivers/gpio/intel_gpio.c10
-rw-r--r--drivers/pinctrl/intel/pinctrl.c2
-rw-r--r--drivers/serial/Kconfig32
-rw-r--r--drivers/serial/Makefile1
-rw-r--r--drivers/serial/ns16550.c79
-rw-r--r--drivers/serial/serial_coreboot.c46
-rw-r--r--drivers/spi/ich.c12
-rw-r--r--include/configs/slimbootloader.h13
-rw-r--r--include/ns16550.h16
26 files changed, 308 insertions, 157 deletions
diff --git a/.azure-pipelines.yml b/.azure-pipelines.yml
index 916ab84ea0..a0713dd66c 100644
--- a/.azure-pipelines.yml
+++ b/.azure-pipelines.yml
@@ -1,5 +1,5 @@
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
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 89b93e5de2..b733d2264e 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -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
diff --git a/arch/x86/cpu/apollolake/Kconfig b/arch/x86/cpu/apollolake/Kconfig
index fcff176c27..a760e0ac68 100644
--- a/arch/x86/cpu/apollolake/Kconfig
+++ b/arch/x86/cpu/apollolake/Kconfig
@@ -39,6 +39,7 @@ config INTEL_APOLLOLAKE
imply HAVE_X86_FIT
imply INTEL_GPIO
imply SMP
+ imply HAVE_ITSS
if INTEL_APOLLOLAKE
diff --git a/arch/x86/cpu/apollolake/Makefile b/arch/x86/cpu/apollolake/Makefile
index 1760df54d8..f99f2c6473 100644
--- a/arch/x86/cpu/apollolake/Makefile
+++ b/arch/x86/cpu/apollolake/Makefile
@@ -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
diff --git a/arch/x86/cpu/i386/cpu.c b/arch/x86/cpu/i386/cpu.c
index 1592b2c9d3..c8da7f10e9 100644
--- a/arch/x86/cpu/i386/cpu.c
+++ b/arch/x86/cpu/i386/cpu.c
@@ -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);
diff --git a/arch/x86/cpu/intel_common/Makefile b/arch/x86/cpu/intel_common/Makefile
index cc4e1c962b..e22c70781d 100644
--- a/arch/x86/cpu/intel_common/Makefile
+++ b/arch/x86/cpu/intel_common/Makefile
@@ -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
diff --git a/arch/x86/cpu/apollolake/itss.c b/arch/x86/cpu/intel_common/itss.c
index 8789f8e6bb..9df51adecc 100644
--- a/arch/x86/cpu/apollolake/itss.c
+++ b/arch/x86/cpu/intel_common/itss.c
@@ -1,6 +1,6 @@
// 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),
};
diff --git a/arch/x86/cpu/slimbootloader/serial.c b/arch/x86/cpu/slimbootloader/serial.c
index 7b44a59bff..bab54b18df 100644
--- a/arch/x86/cpu/slimbootloader/serial.c
+++ b/arch/x86/cpu/slimbootloader/serial.c
@@ -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;
}
diff --git a/arch/x86/cpu/start.S b/arch/x86/cpu/start.S
index 01524635e9..26cf995db2 100644
--- a/arch/x86/cpu/start.S
+++ b/arch/x86/cpu/start.S
@@ -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.
diff --git a/arch/x86/cpu/start16.S b/arch/x86/cpu/start16.S
index 54f4ff6662..292e750508 100644
--- a/arch/x86/cpu/start16.S
+++ b/arch/x86/cpu/start16.S
@@ -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
diff --git a/arch/x86/dts/chromebook_coral.dts b/arch/x86/dts/chromebook_coral.dts
index 24fcbb5063..a1820fa187 100644
--- a/arch/x86/dts/chromebook_coral.dts
+++ b/arch/x86/dts/chromebook_coral.dts
@@ -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
diff --git a/arch/x86/dts/coreboot.dts b/arch/x86/dts/coreboot.dts
index a88da6eafd..38ddaafa19 100644
--- a/arch/x86/dts/coreboot.dts
+++ b/arch/x86/dts/coreboot.dts
@@ -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";
};
diff --git a/arch/x86/include/asm/coreboot_tables.h b/arch/x86/include/asm/coreboot_tables.h
index 2c54e24e02..61de0077d7 100644
--- a/arch/x86/include/asm/coreboot_tables.h
+++ b/arch/x86/include/asm/coreboot_tables.h
@@ -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
diff --git a/arch/x86/include/asm/arch-apollolake/itss.h b/arch/x86/include/asm/itss.h
index 1e29503974..c75d8fe8c2 100644
--- a/arch/x86/include/asm/arch-apollolake/itss.h
+++ b/arch/x86/include/asm/itss.h
@@ -1,5 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
+ * Interrupt Timer Subsystem
+ *
* Copyright (C) 2017 Intel Corporation.
* Copyright 2019 Google LLC
*
diff --git a/configs/edison_defconfig b/configs/edison_defconfig
index 14b2eec3ba..58707d619a 100644
--- a/configs/edison_defconfig
+++ b/configs/edison_defconfig
@@ -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
diff --git a/doc/board/google/chromebook_coral.rst b/doc/board/google/chromebook_coral.rst
index 515fd06d76..5dc3c97c3d 100644
--- a/doc/board/google/chromebook_coral.rst
+++ b/doc/board/google/chromebook_coral.rst
@@ -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
diff --git a/doc/board/intel/slimbootloader.rst b/doc/board/intel/slimbootloader.rst
index 375e676804..a8c41b1aa7 100644
--- a/doc/board/intel/slimbootloader.rst
+++ b/doc/board/intel/slimbootloader.rst
@@ -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)
diff --git a/drivers/gpio/intel_gpio.c b/drivers/gpio/intel_gpio.c
index 4bf1c9ddc4..67b8b80b9d 100644
--- a/drivers/gpio/intel_gpio.c
+++ b/drivers/gpio/intel_gpio.c
@@ -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;
diff --git a/drivers/pinctrl/intel/pinctrl.c b/drivers/pinctrl/intel/pinctrl.c
index 4875a3b0b5..5bf5d8b0e2 100644
--- a/drivers/pinctrl/intel/pinctrl.c
+++ b/drivers/pinctrl/intel/pinctrl.c
@@ -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>
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index bd95f70b61..cd2e098883 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -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
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 06ee30697d..76b1811510 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -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
diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c
index 9851663dc5..31f6cfe421 100644
--- a/drivers/serial/ns16550.c
+++ b/drivers/serial/ns16550.c
@@ -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);
+ }
+ } else if (plat->flags & NS16550_FLAG_BE) {
+ writeb(value, addr + (1 << plat->reg_shift) - 1);
+ } else {
+ writeb(value, addr);
+ }
+}
+
+static int serial_in_dynamic(struct ns16550_platdata *plat, u8 *addr)
+{
+ if (plat->flags & NS16550_FLAG_IO) {
+ return inb(addr);
+ } else if (plat->reg_width == 4) {
+ if (plat->flags & NS16550_FLAG_ENDIAN) {
+ if (plat->flags & NS16550_FLAG_BE)
+ return in_be32(addr);
+ else
+ return in_le32(addr);
+ } else {
+ return readl(addr);
+ }
+ } else if (plat->flags & NS16550_FLAG_BE) {
+ return readb(addr + (1 << plat->reg_shift) - 1);
+ } else {
+ return readb(addr);
+ }
+}
+#else
+static inline void serial_out_dynamic(struct ns16550_platdata *plat, u8 *addr,
+ int value)
+{
+}
+
+static inline int serial_in_dynamic(struct ns16550_platdata *plat, u8 *addr)
+{
+ return 0;
+}
+
+#endif /* CONFIG_NS16550_DYNAMIC */
+
static void ns16550_writeb(NS16550_t port, int offset, int value)
{
struct ns16550_platdata *plat = port->plat;
unsigned char *addr;
offset *= 1 << plat->reg_shift;
- addr = (unsigned char *)plat->base + offset;
+ addr = (unsigned char *)plat->base + offset + plat->reg_offset;
- /*
- * As far as we know it doesn't make sense to support selection of
- * these options at run-time, so use the existing CONFIG options.
- */
- serial_out_shift(addr + plat->reg_offset, plat->reg_shift, value);
+ if (IS_ENABLED(CONFIG_NS16550_DYNAMIC))
+ serial_out_dynamic(plat, addr, value);
+ else
+ serial_out_shift(addr, plat->reg_shift, value);
}
static int ns16550_readb(NS16550_t port, int offset)
@@ -114,9 +174,12 @@ static int ns16550_readb(NS16550_t port, int offset)
unsigned char *addr;
offset *= 1 << plat->reg_shift;
- addr = (unsigned char *)plat->base + offset;
+ addr = (unsigned char *)plat->base + offset + plat->reg_offset;
- return serial_in_shift(addr + plat->reg_offset, plat->reg_shift);
+ if (IS_ENABLED(CONFIG_NS16550_DYNAMIC))
+ return serial_in_dynamic(plat, addr);
+ else
+ return serial_in_shift(addr, plat->reg_shift);
}
static u32 ns16550_getfcr(NS16550_t port)
diff --git a/drivers/serial/serial_coreboot.c b/drivers/serial/serial_coreboot.c
new file mode 100644
index 0000000000..ccab347514
--- /dev/null
+++ b/drivers/serial/serial_coreboot.c
@@ -0,0 +1,46 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * UART support for U-Boot when launched from Coreboot
+ *
+ * Copyright 2019 Google LLC
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <ns16550.h>
+#include <serial.h>
+#include <asm/arch/sysinfo.h>
+
+static int coreboot_ofdata_to_platdata(struct udevice *dev)
+{
+ struct ns16550_platdata *plat = dev_get_platdata(dev);
+ struct cb_serial *cb_info = lib_sysinfo.serial;
+
+ plat->base = cb_info->baseaddr;
+ plat->reg_shift = cb_info->regwidth == 4 ? 2 : 0;
+ plat->reg_width = cb_info->regwidth;
+ plat->clock = cb_info->input_hertz;
+ plat->fcr = UART_FCR_DEFVAL;
+ plat->flags = 0;
+ if (cb_info->type == CB_SERIAL_TYPE_IO_MAPPED)
+ plat->flags |= NS16550_FLAG_IO;
+
+ return 0;
+}
+
+static const struct udevice_id coreboot_serial_ids[] = {
+ { .compatible = "coreboot-serial" },
+ { },
+};
+
+U_BOOT_DRIVER(coreboot_uart) = {
+ .name = "coreboot_uart",
+ .id = UCLASS_SERIAL,
+ .of_match = coreboot_serial_ids,
+ .priv_auto_alloc_size = sizeof(struct NS16550),
+ .platdata_auto_alloc_size = sizeof(struct ns16550_platdata),
+ .ofdata_to_platdata = coreboot_ofdata_to_platdata,
+ .probe = ns16550_serial_probe,
+ .ops = &ns16550_serial_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/spi/ich.c b/drivers/spi/ich.c
index 133b25b72e..a9d7715a55 100644
--- a/drivers/spi/ich.c
+++ b/drivers/spi/ich.c
@@ -562,16 +562,8 @@ static int ich_spi_exec_op_hwseq(struct spi_slave *slave,
return 0; /* ignore */
case SPINOR_OP_BE_4K:
cycle = HSFSTS_CYCLE_4K_ERASE;
- while (len) {
- uint xfer_len = 0x1000;
-
- ret = exec_sync_hwseq_xfer(regs, cycle, offset, 0);
- if (ret)
- return ret;
- offset += xfer_len;
- len -= xfer_len;
- }
- return 0;
+ ret = exec_sync_hwseq_xfer(regs, cycle, offset, 0);
+ return ret;
default:
debug("Unknown cycle %x\n", op->cmd.opcode);
return -EINVAL;
diff --git a/include/configs/slimbootloader.h b/include/configs/slimbootloader.h
index e0011ed446..b8169072cc 100644
--- a/include/configs/slimbootloader.h
+++ b/include/configs/slimbootloader.h
@@ -8,19 +8,6 @@
#include <configs/x86-common.h>
-/*
- * By default, CONFIG_SYS_NS16550_PORT_MAPPED is enabled for port io serial.
- * To use mmio base serial, enable CONFIG_SYS_NS16550_MEM32 and disable
- * CONFIG_SYS_NS16550_PORT_MAPPED until ns16550 driver supports serial port
- * configuration in run-time.
- *
- * #define CONFIG_SYS_NS16550_MEM32
- * #undef CONFIG_SYS_NS16550_PORT_MAPPED
- */
-#ifdef CONFIG_SYS_NS16550_MEM32
-#undef CONFIG_SYS_NS16550_PORT_MAPPED
-#endif
-
#define CONFIG_STD_DEVICES_SETTINGS \
"stdin=serial,i8042-kbd,usbkbd\0" \
"stdout=serial\0" \
diff --git a/include/ns16550.h b/include/ns16550.h
index 701efeea85..18c9077755 100644
--- a/include/ns16550.h
+++ b/include/ns16550.h
@@ -31,6 +31,9 @@
#define CONFIG_SYS_NS16550_REG_SIZE (-1)
#endif
+#ifdef CONFIG_NS16550_DYNAMIC
+#define UART_REG(x) unsigned char x
+#else
#if !defined(CONFIG_SYS_NS16550_REG_SIZE) || (CONFIG_SYS_NS16550_REG_SIZE == 0)
#error "Please define NS16550 registers size."
#elif defined(CONFIG_SYS_NS16550_MEM32) && !defined(CONFIG_DM_SERIAL)
@@ -44,14 +47,24 @@
unsigned char x; \
unsigned char postpad_##x[-CONFIG_SYS_NS16550_REG_SIZE - 1];
#endif
+#endif /* CONFIG_NS16550_DYNAMIC */
+
+enum ns16550_flags {
+ NS16550_FLAG_IO = 1 << 0, /* Use I/O access (else mem-mapped) */
+ NS16550_FLAG_ENDIAN = 1 << 1, /* Use out_le/be_32() */
+ NS16550_FLAG_BE = 1 << 2, /* Big-endian access (else little) */
+};
/**
* struct ns16550_platdata - information about a NS16550 port
*
* @base: Base register address
- * @reg_width: IO accesses size of registers (in bytes)
+ * @reg_width: IO accesses size of registers (in bytes, 1 or 4)
* @reg_shift: Shift size of registers (0=byte, 1=16bit, 2=32bit...)
+ * @reg_offset: Offset to start of registers (normally 0)
* @clock: UART base clock speed in Hz
+ * @fcr: Offset of FCR register (normally UART_FCR_DEFVAL)
+ * @flags: A few flags (enum ns16550_flags)
* @bdf: PCI slot/function (pci_dev_t)
*/
struct ns16550_platdata {
@@ -61,6 +74,7 @@ struct ns16550_platdata {
int reg_offset;
int clock;
u32 fcr;
+ int flags;
#if defined(CONFIG_PCI) && defined(CONFIG_SPL)
int bdf;
#endif