[U-Boot] [RFC PATCH 0/6] x86: New Intel Quark SoC support

This series adds the first step of bare support for the Intel Quark SoC support which can be validated on Intel Galileo board.
Intel Quark is a line of 32-bit x86 SoCs by Intel, designed for small size and low power consumption, and targeted at new markets including wearable devices. They are smaller and slower than Atom processors and consume less power. They lack support for SIMD instruction sets (such as MMX and SSE) and only support embedded operating systems. Quark powers the Intel Galileo developer microcontroller board. The CPU instruction set is the same as Pentium (P54C/i586) CPU.
Intel decided to completely publish Quark's hardware specification to software developers, which includes an SoC datasheet, a UEFI Firmware Writer's Guide, and a complete reference source code for the UEFI BIOS which is pre-flahsed on the Galileo board. As of today, the only BIOS for Galileo is the Intel one with UEFI inteface only. There is no CSM support yet in that BIOS, neither any 3rd party BIOS vendor provides support to Quark SoC.
Note there are two generation of Galileo boards, aka gen1 and gen2. Currently the development work is on gen2, but once we get it boot, we can easily add the gen1 board (old version).
With this patch series, the generated u-boot.rom could boot the Intel Galileo board up to fdt relocate, where U-Boot hangs because the DRAM is not initializaed yet. A follow up patch series will be sent soon to add support for Memory Reference Code (MRC).
Note this patch series may need rebase after Simon's Minnowmax support patch series is applied.
Bin Meng (6): x86: Add header files for Intel Quark SoC defines x86: quark: Add routines to access message bus registers x86: quark: Add Cache-As-RAM initialization x86: Add basic Intel Quark processor support x86: Add basic Intel Galileo board support x86: Enable the Intel quark/galileo build
arch/x86/Kconfig | 17 +++++ arch/x86/cpu/Makefile | 1 + arch/x86/cpu/quark/Kconfig | 63 +++++++++++++++++ arch/x86/cpu/quark/Makefile | 8 +++ arch/x86/cpu/quark/car.S | 105 +++++++++++++++++++++++++++++ arch/x86/cpu/quark/dram.c | 39 +++++++++++ arch/x86/cpu/quark/msg_port.c | 76 +++++++++++++++++++++ arch/x86/cpu/quark/pci.c | 70 +++++++++++++++++++ arch/x86/cpu/quark/quark.c | 44 ++++++++++++ arch/x86/dts/Makefile | 3 +- arch/x86/dts/galileo.dts | 43 ++++++++++++ arch/x86/include/asm/arch-quark/device.h | 28 ++++++++ arch/x86/include/asm/arch-quark/gpio.h | 13 ++++ arch/x86/include/asm/arch-quark/msg_port.h | 93 +++++++++++++++++++++++++ arch/x86/include/asm/arch-quark/quark.h | 57 ++++++++++++++++ board/intel/galileo/Kconfig | 21 ++++++ board/intel/galileo/MAINTAINERS | 6 ++ board/intel/galileo/Makefile | 7 ++ board/intel/galileo/galileo.c | 19 ++++++ board/intel/galileo/start.S | 9 +++ configs/galileo_defconfig | 6 ++ include/configs/galileo.h | 53 +++++++++++++++ 22 files changed, 780 insertions(+), 1 deletion(-) create mode 100644 arch/x86/cpu/quark/Kconfig create mode 100644 arch/x86/cpu/quark/Makefile create mode 100644 arch/x86/cpu/quark/car.S create mode 100644 arch/x86/cpu/quark/dram.c create mode 100644 arch/x86/cpu/quark/msg_port.c create mode 100644 arch/x86/cpu/quark/pci.c create mode 100644 arch/x86/cpu/quark/quark.c create mode 100644 arch/x86/dts/galileo.dts create mode 100644 arch/x86/include/asm/arch-quark/device.h create mode 100644 arch/x86/include/asm/arch-quark/gpio.h create mode 100644 arch/x86/include/asm/arch-quark/msg_port.h create mode 100644 arch/x86/include/asm/arch-quark/quark.h create mode 100644 board/intel/galileo/Kconfig create mode 100644 board/intel/galileo/MAINTAINERS create mode 100644 board/intel/galileo/Makefile create mode 100644 board/intel/galileo/galileo.c create mode 100644 board/intel/galileo/start.S create mode 100644 configs/galileo_defconfig create mode 100644 include/configs/galileo.h

device.h for integrated pci devices' bdf on Quark SoC and quark.h for various memory-mapped and i/o-mapped base addresses within SoC.
Signed-off-by: Bin Meng bmeng.cn@gmail.com ---
arch/x86/include/asm/arch-quark/device.h | 28 ++++++++++++++++ arch/x86/include/asm/arch-quark/quark.h | 57 ++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 arch/x86/include/asm/arch-quark/device.h create mode 100644 arch/x86/include/asm/arch-quark/quark.h
diff --git a/arch/x86/include/asm/arch-quark/device.h b/arch/x86/include/asm/arch-quark/device.h new file mode 100644 index 0000000..4af3ded --- /dev/null +++ b/arch/x86/include/asm/arch-quark/device.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2015, Bin Meng bmeng.cn@gmail.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _QUARK_DEVICE_H_ +#define _QUARK_DEVICE_H_ + +#include <pci.h> + +#define QUARK_HOST_BRIDGE PCI_BDF(0, 0, 0) +#define QUARK_MMC_SDIO PCI_BDF(0, 20, 0) +#define QUARK_UART0 PCI_BDF(0, 20, 1) +#define QUARK_USB_DEVICE PCI_BDF(0, 20, 2) +#define QUARK_USB_EHCI PCI_BDF(0, 20, 3) +#define QUARK_USB_OHCI PCI_BDF(0, 20, 4) +#define QUARK_UART1 PCI_BDF(0, 20, 5) +#define QUARK_EMAC0 PCI_BDF(0, 20, 6) +#define QUARK_EMAC1 PCI_BDF(0, 20, 7) +#define QUARK_SPI0 PCI_BDF(0, 21, 0) +#define QUARK_SPI1 PCI_BDF(0, 21, 1) +#define QUARK_I2C_GPIO PCI_BDF(0, 21, 2) +#define QUARK_PCIE0 PCI_BDF(0, 23, 0) +#define QUARK_PCIE1 PCI_BDF(0, 23, 1) +#define QUARK_LEGACY_BRIDGE PCI_BDF(0, 31, 0) + +#endif /* _QUARK_DEVICE_H_ */ diff --git a/arch/x86/include/asm/arch-quark/quark.h b/arch/x86/include/asm/arch-quark/quark.h new file mode 100644 index 0000000..6eef2d1 --- /dev/null +++ b/arch/x86/include/asm/arch-quark/quark.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2015, Bin Meng bmeng.cn@gmail.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _QUARK_H_ +#define _QUARK_H_ + +/* The following are Memory Base Addresses */ + +/* DRAM */ +#define DRAM_BASE 0x00000000 +#define DRAM_MAX_SIZE 0x80000000 + +/* eSRAM */ +#define ESRAM_BASE (DRAM_BASE + DRAM_MAX_SIZE) +#define ESRAM_SIZE 0x80000 + +/* SMM Control */ + +/* PCIe ECAM */ +#define PCIE_ECAM_BASE 0xE0000000 + +/* RCBA */ +#define RCBA_BASE 0xFED1C000 + +/* Memory BAR Enable */ +#define MEM_BAR_EN 0x00000001 + +/* 64KiB of RMU binary in flash */ +#define RMU_BINARY_SIZE 0x10000 + +/* The following are I/O Base Addresses */ + +/* ACPI PM1 Block */ +#define ACPI_PM1_BASE 0x1000 + +/* ACPI P Block */ +#define ACPI_P_BASE 0x1010 + +/* SPI DMA */ +#define SPI_DMA_BASE 0x1020 + +/* GPIO */ +#define GPIO_BASE 0x1080 + +/* GPE0 */ +#define GPE0_BASE 0x1100 + +/* WDT */ +#define WDT_BASE 0x1140 + +/* I/O BAR Enable */ +#define IO_BAR_EN 0x80000000 + +#endif /* _QUARK_H_ */

Hi Bin,
On 28 January 2015 at 07:19, Bin Meng bmeng.cn@gmail.com wrote:
device.h for integrated pci devices' bdf on Quark SoC and quark.h for various memory-mapped and i/o-mapped base addresses within SoC.
Signed-off-by: Bin Meng bmeng.cn@gmail.com
arch/x86/include/asm/arch-quark/device.h | 28 ++++++++++++++++ arch/x86/include/asm/arch-quark/quark.h | 57 ++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 arch/x86/include/asm/arch-quark/device.h create mode 100644 arch/x86/include/asm/arch-quark/quark.h
diff --git a/arch/x86/include/asm/arch-quark/device.h b/arch/x86/include/asm/arch-quark/device.h new file mode 100644 index 0000000..4af3ded --- /dev/null +++ b/arch/x86/include/asm/arch-quark/device.h @@ -0,0 +1,28 @@ +/*
- Copyright (C) 2015, Bin Meng bmeng.cn@gmail.com
- SPDX-License-Identifier: GPL-2.0+
- */
+#ifndef _QUARK_DEVICE_H_ +#define _QUARK_DEVICE_H_
+#include <pci.h>
+#define QUARK_HOST_BRIDGE PCI_BDF(0, 0, 0) +#define QUARK_MMC_SDIO PCI_BDF(0, 20, 0) +#define QUARK_UART0 PCI_BDF(0, 20, 1) +#define QUARK_USB_DEVICE PCI_BDF(0, 20, 2) +#define QUARK_USB_EHCI PCI_BDF(0, 20, 3) +#define QUARK_USB_OHCI PCI_BDF(0, 20, 4) +#define QUARK_UART1 PCI_BDF(0, 20, 5) +#define QUARK_EMAC0 PCI_BDF(0, 20, 6) +#define QUARK_EMAC1 PCI_BDF(0, 20, 7) +#define QUARK_SPI0 PCI_BDF(0, 21, 0) +#define QUARK_SPI1 PCI_BDF(0, 21, 1) +#define QUARK_I2C_GPIO PCI_BDF(0, 21, 2) +#define QUARK_PCIE0 PCI_BDF(0, 23, 0) +#define QUARK_PCIE1 PCI_BDF(0, 23, 1) +#define QUARK_LEGACY_BRIDGE PCI_BDF(0, 31, 0)
+#endif /* _QUARK_DEVICE_H_ */ diff --git a/arch/x86/include/asm/arch-quark/quark.h b/arch/x86/include/asm/arch-quark/quark.h new file mode 100644 index 0000000..6eef2d1 --- /dev/null +++ b/arch/x86/include/asm/arch-quark/quark.h @@ -0,0 +1,57 @@ +/*
- Copyright (C) 2015, Bin Meng bmeng.cn@gmail.com
- SPDX-License-Identifier: GPL-2.0+
- */
+#ifndef _QUARK_H_ +#define _QUARK_H_
+/* The following are Memory Base Addresses */
+/* DRAM */ +#define DRAM_BASE 0x00000000 +#define DRAM_MAX_SIZE 0x80000000
+/* eSRAM */ +#define ESRAM_BASE (DRAM_BASE + DRAM_MAX_SIZE) +#define ESRAM_SIZE 0x80000
+/* SMM Control */
+/* PCIe ECAM */ +#define PCIE_ECAM_BASE 0xE0000000
Can we use lower case hex?
I suppose this one will move to Kconfig before we apply it?
What about the others?
+/* RCBA */ +#define RCBA_BASE 0xFED1C000
+/* Memory BAR Enable */ +#define MEM_BAR_EN 0x00000001
+/* 64KiB of RMU binary in flash */ +#define RMU_BINARY_SIZE 0x10000
+/* The following are I/O Base Addresses */
+/* ACPI PM1 Block */ +#define ACPI_PM1_BASE 0x1000
+/* ACPI P Block */ +#define ACPI_P_BASE 0x1010
+/* SPI DMA */ +#define SPI_DMA_BASE 0x1020
+/* GPIO */ +#define GPIO_BASE 0x1080
+/* GPE0 */ +#define GPE0_BASE 0x1100
+/* WDT */ +#define WDT_BASE 0x1140
+/* I/O BAR Enable */ +#define IO_BAR_EN 0x80000000
+#endif /* _QUARK_H_ */
1.8.2.1
Regards, Simon

Hi Simon,
On Thu, Jan 29, 2015 at 2:04 AM, Simon Glass sjg@chromium.org wrote:
Hi Bin,
On 28 January 2015 at 07:19, Bin Meng bmeng.cn@gmail.com wrote:
device.h for integrated pci devices' bdf on Quark SoC and quark.h for various memory-mapped and i/o-mapped base addresses within SoC.
Signed-off-by: Bin Meng bmeng.cn@gmail.com
arch/x86/include/asm/arch-quark/device.h | 28 ++++++++++++++++ arch/x86/include/asm/arch-quark/quark.h | 57 ++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 arch/x86/include/asm/arch-quark/device.h create mode 100644 arch/x86/include/asm/arch-quark/quark.h
diff --git a/arch/x86/include/asm/arch-quark/device.h b/arch/x86/include/asm/arch-quark/device.h new file mode 100644 index 0000000..4af3ded --- /dev/null +++ b/arch/x86/include/asm/arch-quark/device.h @@ -0,0 +1,28 @@ +/*
- Copyright (C) 2015, Bin Meng bmeng.cn@gmail.com
- SPDX-License-Identifier: GPL-2.0+
- */
+#ifndef _QUARK_DEVICE_H_ +#define _QUARK_DEVICE_H_
+#include <pci.h>
+#define QUARK_HOST_BRIDGE PCI_BDF(0, 0, 0) +#define QUARK_MMC_SDIO PCI_BDF(0, 20, 0) +#define QUARK_UART0 PCI_BDF(0, 20, 1) +#define QUARK_USB_DEVICE PCI_BDF(0, 20, 2) +#define QUARK_USB_EHCI PCI_BDF(0, 20, 3) +#define QUARK_USB_OHCI PCI_BDF(0, 20, 4) +#define QUARK_UART1 PCI_BDF(0, 20, 5) +#define QUARK_EMAC0 PCI_BDF(0, 20, 6) +#define QUARK_EMAC1 PCI_BDF(0, 20, 7) +#define QUARK_SPI0 PCI_BDF(0, 21, 0) +#define QUARK_SPI1 PCI_BDF(0, 21, 1) +#define QUARK_I2C_GPIO PCI_BDF(0, 21, 2) +#define QUARK_PCIE0 PCI_BDF(0, 23, 0) +#define QUARK_PCIE1 PCI_BDF(0, 23, 1) +#define QUARK_LEGACY_BRIDGE PCI_BDF(0, 31, 0)
+#endif /* _QUARK_DEVICE_H_ */ diff --git a/arch/x86/include/asm/arch-quark/quark.h b/arch/x86/include/asm/arch-quark/quark.h new file mode 100644 index 0000000..6eef2d1 --- /dev/null +++ b/arch/x86/include/asm/arch-quark/quark.h @@ -0,0 +1,57 @@ +/*
- Copyright (C) 2015, Bin Meng bmeng.cn@gmail.com
- SPDX-License-Identifier: GPL-2.0+
- */
+#ifndef _QUARK_H_ +#define _QUARK_H_
+/* The following are Memory Base Addresses */
+/* DRAM */ +#define DRAM_BASE 0x00000000 +#define DRAM_MAX_SIZE 0x80000000
+/* eSRAM */ +#define ESRAM_BASE (DRAM_BASE + DRAM_MAX_SIZE) +#define ESRAM_SIZE 0x80000
+/* SMM Control */
+/* PCIe ECAM */ +#define PCIE_ECAM_BASE 0xE0000000
Can we use lower case hex?
Sure. But I wonder if there is any coding standard that requires such address needs to be in lower case hex?
I suppose this one will move to Kconfig before we apply it?
Yes, this one can be moved to Kconfig after your Minowmax series.
What about the others?
These base addresses can be relocatable, just like the PCIe ECAM, but requires the person who knows what they exactly mean. These values are actually suggested by Intel's UEFI firmware writer guide, so I would like to put them just in header file. However it there any rule on what needs to be put in Kconfig?
+/* RCBA */ +#define RCBA_BASE 0xFED1C000
+/* Memory BAR Enable */ +#define MEM_BAR_EN 0x00000001
+/* 64KiB of RMU binary in flash */ +#define RMU_BINARY_SIZE 0x10000
+/* The following are I/O Base Addresses */
+/* ACPI PM1 Block */ +#define ACPI_PM1_BASE 0x1000
+/* ACPI P Block */ +#define ACPI_P_BASE 0x1010
+/* SPI DMA */ +#define SPI_DMA_BASE 0x1020
+/* GPIO */ +#define GPIO_BASE 0x1080
+/* GPE0 */ +#define GPE0_BASE 0x1100
+/* WDT */ +#define WDT_BASE 0x1140
+/* I/O BAR Enable */ +#define IO_BAR_EN 0x80000000
+#endif /* _QUARK_H_ */
Regards, Bin

Hi Bin,
On 28 January 2015 at 18:58, Bin Meng bmeng.cn@gmail.com wrote:
Hi Simon,
On Thu, Jan 29, 2015 at 2:04 AM, Simon Glass sjg@chromium.org wrote:
Hi Bin,
On 28 January 2015 at 07:19, Bin Meng bmeng.cn@gmail.com wrote:
device.h for integrated pci devices' bdf on Quark SoC and quark.h for various memory-mapped and i/o-mapped base addresses within SoC.
Signed-off-by: Bin Meng bmeng.cn@gmail.com
arch/x86/include/asm/arch-quark/device.h | 28 ++++++++++++++++ arch/x86/include/asm/arch-quark/quark.h | 57 ++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 arch/x86/include/asm/arch-quark/device.h create mode 100644 arch/x86/include/asm/arch-quark/quark.h
diff --git a/arch/x86/include/asm/arch-quark/device.h b/arch/x86/include/asm/arch-quark/device.h new file mode 100644 index 0000000..4af3ded --- /dev/null +++ b/arch/x86/include/asm/arch-quark/device.h @@ -0,0 +1,28 @@ +/*
- Copyright (C) 2015, Bin Meng bmeng.cn@gmail.com
- SPDX-License-Identifier: GPL-2.0+
- */
+#ifndef _QUARK_DEVICE_H_ +#define _QUARK_DEVICE_H_
+#include <pci.h>
+#define QUARK_HOST_BRIDGE PCI_BDF(0, 0, 0) +#define QUARK_MMC_SDIO PCI_BDF(0, 20, 0) +#define QUARK_UART0 PCI_BDF(0, 20, 1) +#define QUARK_USB_DEVICE PCI_BDF(0, 20, 2) +#define QUARK_USB_EHCI PCI_BDF(0, 20, 3) +#define QUARK_USB_OHCI PCI_BDF(0, 20, 4) +#define QUARK_UART1 PCI_BDF(0, 20, 5) +#define QUARK_EMAC0 PCI_BDF(0, 20, 6) +#define QUARK_EMAC1 PCI_BDF(0, 20, 7) +#define QUARK_SPI0 PCI_BDF(0, 21, 0) +#define QUARK_SPI1 PCI_BDF(0, 21, 1) +#define QUARK_I2C_GPIO PCI_BDF(0, 21, 2) +#define QUARK_PCIE0 PCI_BDF(0, 23, 0) +#define QUARK_PCIE1 PCI_BDF(0, 23, 1) +#define QUARK_LEGACY_BRIDGE PCI_BDF(0, 31, 0)
+#endif /* _QUARK_DEVICE_H_ */ diff --git a/arch/x86/include/asm/arch-quark/quark.h b/arch/x86/include/asm/arch-quark/quark.h new file mode 100644 index 0000000..6eef2d1 --- /dev/null +++ b/arch/x86/include/asm/arch-quark/quark.h @@ -0,0 +1,57 @@ +/*
- Copyright (C) 2015, Bin Meng bmeng.cn@gmail.com
- SPDX-License-Identifier: GPL-2.0+
- */
+#ifndef _QUARK_H_ +#define _QUARK_H_
+/* The following are Memory Base Addresses */
+/* DRAM */ +#define DRAM_BASE 0x00000000 +#define DRAM_MAX_SIZE 0x80000000
+/* eSRAM */ +#define ESRAM_BASE (DRAM_BASE + DRAM_MAX_SIZE) +#define ESRAM_SIZE 0x80000
+/* SMM Control */
+/* PCIe ECAM */ +#define PCIE_ECAM_BASE 0xE0000000
Can we use lower case hex?
Sure. But I wonder if there is any coding standard that requires such address needs to be in lower case hex?
Only that it's nice to be consistent and I've tried to use lower case in x86.
I suppose this one will move to Kconfig before we apply it?
Yes, this one can be moved to Kconfig after your Minowmax series.
What about the others?
These base addresses can be relocatable, just like the PCIe ECAM, but requires the person who knows what they exactly mean. These values are actually suggested by Intel's UEFI firmware writer guide, so I would like to put them just in header file. However it there any rule on what needs to be put in Kconfig?
Anything starting with CONFIG is all I am aware of. If they are not really configurable then it doesn't make sense to put them in Kconfig.
+/* RCBA */ +#define RCBA_BASE 0xFED1C000
+/* Memory BAR Enable */ +#define MEM_BAR_EN 0x00000001
+/* 64KiB of RMU binary in flash */ +#define RMU_BINARY_SIZE 0x10000
+/* The following are I/O Base Addresses */
+/* ACPI PM1 Block */ +#define ACPI_PM1_BASE 0x1000
+/* ACPI P Block */ +#define ACPI_P_BASE 0x1010
+/* SPI DMA */ +#define SPI_DMA_BASE 0x1020
+/* GPIO */ +#define GPIO_BASE 0x1080
+/* GPE0 */ +#define GPE0_BASE 0x1100
+/* WDT */ +#define WDT_BASE 0x1140
+/* I/O BAR Enable */ +#define IO_BAR_EN 0x80000000
+#endif /* _QUARK_H_ */
Regards, Simon

In the Quark SoC, some chipset commands are accomplished by utilizing the internal message network within the host bridge (D0:F0). Accesses to this network are accomplished by populating the message control register (MCR), Message Control Register eXtension (MCRX) and the message data register (MDR).
Signed-off-by: Bin Meng bmeng.cn@gmail.com ---
arch/x86/cpu/quark/msg_port.c | 76 ++++++++++++++++++++++++ arch/x86/include/asm/arch-quark/msg_port.h | 93 ++++++++++++++++++++++++++++++ 2 files changed, 169 insertions(+) create mode 100644 arch/x86/cpu/quark/msg_port.c create mode 100644 arch/x86/include/asm/arch-quark/msg_port.h
diff --git a/arch/x86/cpu/quark/msg_port.c b/arch/x86/cpu/quark/msg_port.c new file mode 100644 index 0000000..a04462f --- /dev/null +++ b/arch/x86/cpu/quark/msg_port.c @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2015, Bin Meng bmeng.cn@gmail.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <pci.h> +#include <asm/arch/device.h> +#include <asm/arch/msg_port.h> + +u32 msg_port_read(u8 port, u32 reg) +{ + u32 value; + + pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_EXT_REG, + reg & 0xffffff00); + pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_REG, + MCR_FILL(MSG_OP_READ, port, reg)); + pci_read_config_dword(QUARK_HOST_BRIDGE, MSG_DATA_REG, &value); + + return value; +} + +void msg_port_write(u8 port, u32 reg, u32 value) +{ + pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_DATA_REG, value); + pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_EXT_REG, + reg & 0xffffff00); + pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_REG, + MCR_FILL(MSG_OP_WRITE, port, reg)); +} + +u32 msg_port_alt_read(u8 port, u32 reg) +{ + u32 value; + + pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_EXT_REG, + reg & 0xffffff00); + pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_REG, + MCR_FILL(MSG_OP_ALT_READ, port, reg)); + pci_read_config_dword(QUARK_HOST_BRIDGE, MSG_DATA_REG, &value); + + return value; +} + +void msg_port_alt_write(u8 port, u32 reg, u32 value) +{ + pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_DATA_REG, value); + pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_EXT_REG, + reg & 0xffffff00); + pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_REG, + MCR_FILL(MSG_OP_ALT_WRITE, port, reg)); +} + +u32 msg_port_io_read(u8 port, u32 reg) +{ + u32 value; + + pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_EXT_REG, + reg & 0xffffff00); + pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_REG, + MCR_FILL(MSG_OP_IO_READ, port, reg)); + pci_read_config_dword(QUARK_HOST_BRIDGE, MSG_DATA_REG, &value); + + return value; +} + +void msg_port_io_write(u8 port, u32 reg, u32 value) +{ + pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_DATA_REG, value); + pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_EXT_REG, + reg & 0xffffff00); + pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_REG, + MCR_FILL(MSG_OP_IO_WRITE, port, reg)); +} diff --git a/arch/x86/include/asm/arch-quark/msg_port.h b/arch/x86/include/asm/arch-quark/msg_port.h new file mode 100644 index 0000000..8f40adb --- /dev/null +++ b/arch/x86/include/asm/arch-quark/msg_port.h @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2015, Bin Meng bmeng.cn@gmail.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _QUARK_MSG_PORT_H_ +#define _QUARK_MSG_PORT_H_ + +/* + * In the Quark SoC, some chipset commands are accomplished by utilizing + * the internal message network within the host bridge (D0:F0). Accesses + * to this network are accomplished by populating the message control + * register (MCR), Message Control Register eXtension (MCRX) and the + * message data register (MDR). + */ +#define MSG_CTRL_REG 0xD0 /* Message Control Register */ +#define MSG_CTRL_EXT_REG 0xD4 /* Message Control Register EXT */ +#define MSG_DATA_REG 0xD8 /* Message Data Register */ + +/* Normal Read/Write OpCodes */ +#define MSG_OP_READ 0x10 +#define MSG_OP_WRITE 0x11 + +/* Alternative Read/Write OpCodes */ +#define MSG_OP_ALT_READ 0x06 +#define MSG_OP_ALT_WRITE 0x07 + +/* IO Read/Write OpCodes */ +#define MSG_OP_IO_READ 0x02 +#define MSG_OP_IO_WRITE 0x03 + +#define MCR_FILL(op, port, reg) \ + (((op) << 24) | ((port) << 16) | (((reg) << 8) & 0xff00) | 0xf0) + +/** + * msg_port_read - read a message port register using normal opcode + * + * @port: port number on the message bus + * @reg: register number within a port + * + * @return: message port register value + */ +u32 msg_port_read(u8 port, u32 reg); + +/** + * msg_port_write - write a message port register using normal opcode + * + * @port: port number on the message bus + * @reg: register number within a port + * @value: register value to write + */ +void msg_port_write(u8 port, u32 reg, u32 value); + +/** + * msg_port_alt_read - read a message port register using alternative opcode + * + * @port: port number on the message bus + * @reg: register number within a port + * + * @return: message port register value + */ +u32 msg_port_alt_read(u8 port, u32 reg); + +/** + * msg_port_alt_write - write a message port register using alternative opcode + * + * @port: port number on the message bus + * @reg: register number within a port + * @value: register value to write + */ +void msg_port_alt_write(u8 port, u32 reg, u32 value); + +/** + * msg_port_io_read - read a message port register using I/O opcode + * + * @port: port number on the message bus + * @reg: register number within a port + * + * @return: message port register value + */ +u32 msg_port_io_read(u8 port, u32 reg); + +/** + * msg_port_io_write - write a message port register using I/O opcode + * + * @port: port number on the message bus + * @reg: register number within a port + * @value: register value to write + */ +void msg_port_io_write(u8 port, u32 reg, u32 value); + +#endif /* _QUARK_MSG_PORT_H_ */

Hi Bin,
On 28 January 2015 at 07:19, Bin Meng bmeng.cn@gmail.com wrote:
In the Quark SoC, some chipset commands are accomplished by utilizing the internal message network within the host bridge (D0:F0). Accesses to this network are accomplished by populating the message control register (MCR), Message Control Register eXtension (MCRX) and the message data register (MDR).
Signed-off-by: Bin Meng bmeng.cn@gmail.com
arch/x86/cpu/quark/msg_port.c | 76 ++++++++++++++++++++++++ arch/x86/include/asm/arch-quark/msg_port.h | 93 ++++++++++++++++++++++++++++++ 2 files changed, 169 insertions(+) create mode 100644 arch/x86/cpu/quark/msg_port.c create mode 100644 arch/x86/include/asm/arch-quark/msg_port.h
diff --git a/arch/x86/cpu/quark/msg_port.c b/arch/x86/cpu/quark/msg_port.c new file mode 100644 index 0000000..a04462f --- /dev/null +++ b/arch/x86/cpu/quark/msg_port.c @@ -0,0 +1,76 @@ +/*
- Copyright (C) 2015, Bin Meng bmeng.cn@gmail.com
- SPDX-License-Identifier: GPL-2.0+
- */
+#include <common.h> +#include <pci.h> +#include <asm/arch/device.h> +#include <asm/arch/msg_port.h>
+u32 msg_port_read(u8 port, u32 reg) +{
u32 value;
pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_EXT_REG,
reg & 0xffffff00);
pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_REG,
MCR_FILL(MSG_OP_READ, port, reg));
pci_read_config_dword(QUARK_HOST_BRIDGE, MSG_DATA_REG, &value);
return value;
Interesting - so this uses PCI config space? Does writing to the CTRL_REG actually cause anything to happen?
Could we remove the CTRL write with a function, like
void msg_port_setup(int op, int port, int reg) { pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_REG, (((op) << 24) | ((port) << 16) | (((reg) << 8) & 0xff00) | 0xf0)); }
then we can remove MCR_FILL.
+}
+void msg_port_write(u8 port, u32 reg, u32 value) +{
pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_DATA_REG, value);
pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_EXT_REG,
reg & 0xffffff00);
pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_REG,
MCR_FILL(MSG_OP_WRITE, port, reg));
+}
+u32 msg_port_alt_read(u8 port, u32 reg) +{
u32 value;
pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_EXT_REG,
reg & 0xffffff00);
pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_REG,
MCR_FILL(MSG_OP_ALT_READ, port, reg));
pci_read_config_dword(QUARK_HOST_BRIDGE, MSG_DATA_REG, &value);
return value;
+}
+void msg_port_alt_write(u8 port, u32 reg, u32 value) +{
pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_DATA_REG, value);
pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_EXT_REG,
reg & 0xffffff00);
pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_REG,
MCR_FILL(MSG_OP_ALT_WRITE, port, reg));
+}
+u32 msg_port_io_read(u8 port, u32 reg) +{
u32 value;
pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_EXT_REG,
reg & 0xffffff00);
pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_REG,
MCR_FILL(MSG_OP_IO_READ, port, reg));
pci_read_config_dword(QUARK_HOST_BRIDGE, MSG_DATA_REG, &value);
return value;
+}
+void msg_port_io_write(u8 port, u32 reg, u32 value) +{
pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_DATA_REG, value);
pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_EXT_REG,
reg & 0xffffff00);
pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_REG,
MCR_FILL(MSG_OP_IO_WRITE, port, reg));
+} diff --git a/arch/x86/include/asm/arch-quark/msg_port.h b/arch/x86/include/asm/arch-quark/msg_port.h new file mode 100644 index 0000000..8f40adb --- /dev/null +++ b/arch/x86/include/asm/arch-quark/msg_port.h @@ -0,0 +1,93 @@ +/*
- Copyright (C) 2015, Bin Meng bmeng.cn@gmail.com
- SPDX-License-Identifier: GPL-2.0+
- */
+#ifndef _QUARK_MSG_PORT_H_ +#define _QUARK_MSG_PORT_H_
+/*
- In the Quark SoC, some chipset commands are accomplished by utilizing
- the internal message network within the host bridge (D0:F0). Accesses
- to this network are accomplished by populating the message control
- register (MCR), Message Control Register eXtension (MCRX) and the
- message data register (MDR).
- */
+#define MSG_CTRL_REG 0xD0 /* Message Control Register */ +#define MSG_CTRL_EXT_REG 0xD4 /* Message Control Register EXT */ +#define MSG_DATA_REG 0xD8 /* Message Data Register */
+/* Normal Read/Write OpCodes */ +#define MSG_OP_READ 0x10 +#define MSG_OP_WRITE 0x11
+/* Alternative Read/Write OpCodes */ +#define MSG_OP_ALT_READ 0x06 +#define MSG_OP_ALT_WRITE 0x07
+/* IO Read/Write OpCodes */ +#define MSG_OP_IO_READ 0x02 +#define MSG_OP_IO_WRITE 0x03
+#define MCR_FILL(op, port, reg) \
(((op) << 24) | ((port) << 16) | (((reg) << 8) & 0xff00) | 0xf0)
+/**
- msg_port_read - read a message port register using normal opcode
- @port: port number on the message bus
- @reg: register number within a port
- @return: message port register value
- */
+u32 msg_port_read(u8 port, u32 reg);
+/**
- msg_port_write - write a message port register using normal opcode
- @port: port number on the message bus
- @reg: register number within a port
- @value: register value to write
- */
+void msg_port_write(u8 port, u32 reg, u32 value);
+/**
- msg_port_alt_read - read a message port register using alternative opcode
- @port: port number on the message bus
- @reg: register number within a port
- @return: message port register value
- */
+u32 msg_port_alt_read(u8 port, u32 reg);
+/**
- msg_port_alt_write - write a message port register using alternative opcode
- @port: port number on the message bus
- @reg: register number within a port
- @value: register value to write
- */
+void msg_port_alt_write(u8 port, u32 reg, u32 value);
+/**
- msg_port_io_read - read a message port register using I/O opcode
- @port: port number on the message bus
- @reg: register number within a port
- @return: message port register value
- */
+u32 msg_port_io_read(u8 port, u32 reg);
+/**
- msg_port_io_write - write a message port register using I/O opcode
- @port: port number on the message bus
- @reg: register number within a port
- @value: register value to write
- */
+void msg_port_io_write(u8 port, u32 reg, u32 value);
+#endif /* _QUARK_MSG_PORT_H_ */
1.8.2.1
Regards, Simon

Hi Simon,
On Thu, Jan 29, 2015 at 2:04 AM, Simon Glass sjg@chromium.org wrote:
Hi Bin,
On 28 January 2015 at 07:19, Bin Meng bmeng.cn@gmail.com wrote:
In the Quark SoC, some chipset commands are accomplished by utilizing the internal message network within the host bridge (D0:F0). Accesses to this network are accomplished by populating the message control register (MCR), Message Control Register eXtension (MCRX) and the message data register (MDR).
Signed-off-by: Bin Meng bmeng.cn@gmail.com
arch/x86/cpu/quark/msg_port.c | 76 ++++++++++++++++++++++++ arch/x86/include/asm/arch-quark/msg_port.h | 93 ++++++++++++++++++++++++++++++ 2 files changed, 169 insertions(+) create mode 100644 arch/x86/cpu/quark/msg_port.c create mode 100644 arch/x86/include/asm/arch-quark/msg_port.h
diff --git a/arch/x86/cpu/quark/msg_port.c b/arch/x86/cpu/quark/msg_port.c new file mode 100644 index 0000000..a04462f --- /dev/null +++ b/arch/x86/cpu/quark/msg_port.c @@ -0,0 +1,76 @@ +/*
- Copyright (C) 2015, Bin Meng bmeng.cn@gmail.com
- SPDX-License-Identifier: GPL-2.0+
- */
+#include <common.h> +#include <pci.h> +#include <asm/arch/device.h> +#include <asm/arch/msg_port.h>
+u32 msg_port_read(u8 port, u32 reg) +{
u32 value;
pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_EXT_REG,
reg & 0xffffff00);
pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_REG,
MCR_FILL(MSG_OP_READ, port, reg));
pci_read_config_dword(QUARK_HOST_BRIDGE, MSG_DATA_REG, &value);
return value;
Interesting - so this uses PCI config space? Does writing to the CTRL_REG actually cause anything to happen?
The message port registers are indirectly accessed via 3 registers in PCI configuration space, something like accessing PCI configuration space register, but they are not within PCI configuration space. So this is a two-level indirect access (first pci, then msg).
Could we remove the CTRL write with a function, like
void msg_port_setup(int op, int port, int reg) { pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_REG, (((op) << 24) | ((port) << 16) | (((reg) << 8) & 0xff00) | 0xf0)); }
then we can remove MCR_FILL.
Yes.
[snip]
Regards, Bin

Quark SoC contains an embedded 512KiB SRAM (eSRAM) that is initialized by hardware. eSRAM is the ideal place to be used for Cache-As-RAM (CAR) before system memory is available.
Signed-off-by: Bin Meng bmeng.cn@gmail.com ---
arch/x86/cpu/quark/car.S | 105 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 arch/x86/cpu/quark/car.S
diff --git a/arch/x86/cpu/quark/car.S b/arch/x86/cpu/quark/car.S new file mode 100644 index 0000000..6b7b249 --- /dev/null +++ b/arch/x86/cpu/quark/car.S @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2015, Bin Meng bmeng.cn@gmail.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <config.h> +#include <asm/post.h> +#include <asm/arch/quark.h> + +.globl car_init +car_init: + post_code(POST_CAR_START) + + /* + * Quark SoC contains an embedded 512KiB SRAM (eSRAM) that is + * initialized by hardware. eSRAM is the ideal place to be used + * for Cache-As-RAM (CAR) before system memory is available. + * + * Relocate this eSRAM to a suitable location in the physical + * memory map and enable it. + */ + + /* Host Memory Bound Register P03h:R08h */ + mov $0x00030800, %eax + mov $(DRAM_BASE + DRAM_MAX_SIZE + ESRAM_SIZE), %edx + lea 1f, %esp + jmp msg_port_write +1: + + /* eSRAM Block Page Control Register P05h:R82h = 10000080h */ + mov $0x00058200, %eax + mov $0x10000080, %edx + lea 2f, %esp + jmp msg_port_write +2: + + post_code(POST_CAR_CPU_CACHE) + jmp car_init_ret + +msg_port_read: + /* + * Parameter: + * EAX[23:16] - Message Port ID + * EAX[15:08] - Register Address + * + * Return Value: + * EAX - Message Port Register value + * + * Return Address: ESP + */ + + /* opcode 0x10, all bytes enable 0xf0 */ + or $0x100000f0, %eax + mov %eax, %ebx + + /* Write MCR B0:D0:F0:RD0 */ + mov $0x800000d0, %eax + mov $0xcf8, %dx + out %eax, %dx + mov $0xcfc, %dx + mov %ebx, %eax + out %eax, %dx + + /* Read MDR B0:D0:F0:RD4 */ + mov $0x800000d4, %eax + mov $0xcf8, %dx + out %eax, %dx + mov $0xcfc, %dx + in %dx, %eax + + jmp *%esp + +msg_port_write: + /* + * Parameter: + * EAX[23:16] - Message Port ID + * EAX[15:08] - Register Address + * EDX - Message Port Register value to write + * + * Return Address: ESP + */ + + /* opcode 0x11, all bytes enable 0xf0 */ + or $0x110000f0, %eax + mov %eax, %esi + mov %edx, %edi + + /* Write MDR B0:D0:F0:RD4 */ + mov $0x800000d4, %eax + mov $0xcf8, %dx + out %eax, %dx + mov $0xcfc, %dx + mov %edi, %eax + out %eax, %dx + + /* Write MCR B0:D0:F0:RD0 */ + mov $0x800000d0, %eax + mov $0xcf8, %dx + out %eax, %dx + mov $0xcfc, %dx + mov %esi, %eax + out %eax, %dx + + jmp *%esp

Hi Bin,
On 28 January 2015 at 07:19, Bin Meng bmeng.cn@gmail.com wrote:
Quark SoC contains an embedded 512KiB SRAM (eSRAM) that is initialized by hardware. eSRAM is the ideal place to be used for Cache-As-RAM (CAR) before system memory is available.
Signed-off-by: Bin Meng bmeng.cn@gmail.com
arch/x86/cpu/quark/car.S | 105 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 arch/x86/cpu/quark/car.S
diff --git a/arch/x86/cpu/quark/car.S b/arch/x86/cpu/quark/car.S new file mode 100644 index 0000000..6b7b249 --- /dev/null +++ b/arch/x86/cpu/quark/car.S @@ -0,0 +1,105 @@ +/*
- Copyright (C) 2015, Bin Meng bmeng.cn@gmail.com
- SPDX-License-Identifier: GPL-2.0+
- */
+#include <config.h> +#include <asm/post.h> +#include <asm/arch/quark.h>
+.globl car_init +car_init:
post_code(POST_CAR_START)
/*
* Quark SoC contains an embedded 512KiB SRAM (eSRAM) that is
* initialized by hardware. eSRAM is the ideal place to be used
* for Cache-As-RAM (CAR) before system memory is available.
*
* Relocate this eSRAM to a suitable location in the physical
* memory map and enable it.
*/
/* Host Memory Bound Register P03h:R08h */
mov $0x00030800, %eax
mov $(DRAM_BASE + DRAM_MAX_SIZE + ESRAM_SIZE), %edx
lea 1f, %esp
jmp msg_port_write
+1:
/* eSRAM Block Page Control Register P05h:R82h = 10000080h */
mov $0x00058200, %eax
mov $0x10000080, %edx
lea 2f, %esp
jmp msg_port_write
+2:
post_code(POST_CAR_CPU_CACHE)
jmp car_init_ret
+msg_port_read:
/*
* Parameter:
* EAX[23:16] - Message Port ID
* EAX[15:08] - Register Address
Can we use lower case eax?
*
* Return Value:
* EAX - Message Port Register value
*
* Return Address: ESP
*/
/* opcode 0x10, all bytes enable 0xf0 */
or $0x100000f0, %eax
#define for this and other things in this file?
mov %eax, %ebx
/* Write MCR B0:D0:F0:RD0 */
mov $0x800000d0, %eax
mov $0xcf8, %dx
out %eax, %dx
mov $0xcfc, %dx
mov %ebx, %eax
out %eax, %dx
/* Read MDR B0:D0:F0:RD4 */
mov $0x800000d4, %eax
mov $0xcf8, %dx
out %eax, %dx
mov $0xcfc, %dx
in %dx, %eax
jmp *%esp
+msg_port_write:
/*
* Parameter:
* EAX[23:16] - Message Port ID
* EAX[15:08] - Register Address
* EDX - Message Port Register value to write
*
* Return Address: ESP
*/
/* opcode 0x11, all bytes enable 0xf0 */
or $0x110000f0, %eax
mov %eax, %esi
mov %edx, %edi
/* Write MDR B0:D0:F0:RD4 */
mov $0x800000d4, %eax
mov $0xcf8, %dx
out %eax, %dx
mov $0xcfc, %dx
mov %edi, %eax
out %eax, %dx
/* Write MCR B0:D0:F0:RD0 */
mov $0x800000d0, %eax
mov $0xcf8, %dx
out %eax, %dx
mov $0xcfc, %dx
mov %esi, %eax
out %eax, %dx
jmp *%esp
-- 1.8.2.1
Regards, Simon

Hi Simon,
On Thu, Jan 29, 2015 at 2:04 AM, Simon Glass sjg@chromium.org wrote:
Hi Bin,
On 28 January 2015 at 07:19, Bin Meng bmeng.cn@gmail.com wrote:
Quark SoC contains an embedded 512KiB SRAM (eSRAM) that is initialized by hardware. eSRAM is the ideal place to be used for Cache-As-RAM (CAR) before system memory is available.
Signed-off-by: Bin Meng bmeng.cn@gmail.com
arch/x86/cpu/quark/car.S | 105 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 arch/x86/cpu/quark/car.S
diff --git a/arch/x86/cpu/quark/car.S b/arch/x86/cpu/quark/car.S new file mode 100644 index 0000000..6b7b249 --- /dev/null +++ b/arch/x86/cpu/quark/car.S @@ -0,0 +1,105 @@ +/*
- Copyright (C) 2015, Bin Meng bmeng.cn@gmail.com
- SPDX-License-Identifier: GPL-2.0+
- */
+#include <config.h> +#include <asm/post.h> +#include <asm/arch/quark.h>
+.globl car_init +car_init:
post_code(POST_CAR_START)
/*
* Quark SoC contains an embedded 512KiB SRAM (eSRAM) that is
* initialized by hardware. eSRAM is the ideal place to be used
* for Cache-As-RAM (CAR) before system memory is available.
*
* Relocate this eSRAM to a suitable location in the physical
* memory map and enable it.
*/
/* Host Memory Bound Register P03h:R08h */
mov $0x00030800, %eax
mov $(DRAM_BASE + DRAM_MAX_SIZE + ESRAM_SIZE), %edx
lea 1f, %esp
jmp msg_port_write
+1:
/* eSRAM Block Page Control Register P05h:R82h = 10000080h */
mov $0x00058200, %eax
mov $0x10000080, %edx
lea 2f, %esp
jmp msg_port_write
+2:
post_code(POST_CAR_CPU_CACHE)
jmp car_init_ret
+msg_port_read:
/*
* Parameter:
* EAX[23:16] - Message Port ID
* EAX[15:08] - Register Address
Can we use lower case eax?
Yes.
*
* Return Value:
* EAX - Message Port Register value
*
* Return Address: ESP
*/
/* opcode 0x10, all bytes enable 0xf0 */
or $0x100000f0, %eax
#define for this and other things in this file?
I will try.
mov %eax, %ebx
/* Write MCR B0:D0:F0:RD0 */
mov $0x800000d0, %eax
mov $0xcf8, %dx
out %eax, %dx
mov $0xcfc, %dx
mov %ebx, %eax
out %eax, %dx
/* Read MDR B0:D0:F0:RD4 */
mov $0x800000d4, %eax
mov $0xcf8, %dx
out %eax, %dx
mov $0xcfc, %dx
in %dx, %eax
jmp *%esp
+msg_port_write:
/*
* Parameter:
* EAX[23:16] - Message Port ID
* EAX[15:08] - Register Address
* EDX - Message Port Register value to write
*
* Return Address: ESP
*/
/* opcode 0x11, all bytes enable 0xf0 */
or $0x110000f0, %eax
mov %eax, %esi
mov %edx, %edi
/* Write MDR B0:D0:F0:RD4 */
mov $0x800000d4, %eax
mov $0xcf8, %dx
out %eax, %dx
mov $0xcfc, %dx
mov %edi, %eax
out %eax, %dx
/* Write MCR B0:D0:F0:RD0 */
mov $0x800000d0, %eax
mov $0xcf8, %dx
out %eax, %dx
mov $0xcfc, %dx
mov %esi, %eax
out %eax, %dx
jmp *%esp
--
Regards, Bin

Add minimum codes to support Intel Quark SoC. DRAM initialization is not ready yet so a hardcoded gd->ram_size is assigned.
Signed-off-by: Bin Meng bmeng.cn@gmail.com ---
arch/x86/cpu/quark/Kconfig | 63 ++++++++++++++++++++++++++++++ arch/x86/cpu/quark/Makefile | 8 ++++ arch/x86/cpu/quark/dram.c | 39 +++++++++++++++++++ arch/x86/cpu/quark/pci.c | 70 ++++++++++++++++++++++++++++++++++ arch/x86/cpu/quark/quark.c | 44 +++++++++++++++++++++ arch/x86/include/asm/arch-quark/gpio.h | 13 +++++++ 6 files changed, 237 insertions(+) create mode 100644 arch/x86/cpu/quark/Kconfig create mode 100644 arch/x86/cpu/quark/Makefile create mode 100644 arch/x86/cpu/quark/dram.c create mode 100644 arch/x86/cpu/quark/pci.c create mode 100644 arch/x86/cpu/quark/quark.c create mode 100644 arch/x86/include/asm/arch-quark/gpio.h
diff --git a/arch/x86/cpu/quark/Kconfig b/arch/x86/cpu/quark/Kconfig new file mode 100644 index 0000000..a71cc6c --- /dev/null +++ b/arch/x86/cpu/quark/Kconfig @@ -0,0 +1,63 @@ +# +# Copyright (C) 2015, Bin Meng bmeng.cn@gmail.com +# +# SPDX-License-Identifier: GPL-2.0+ +# + +config INTEL_QUARK + bool + select HAVE_RMU + +if INTEL_QUARK + +config HAVE_RMU + bool "Add a Remote Management Unit (RMU) binary" + help + Select this option to add a Remote Management Unit (RMU) binary + to the resulting U-Boot image. It is a data block (up to 64K) of + machine specific code which must be put in the flash for the RMU + within the Quark SoC processor to access when powered up before + system BIOS is executed. + +config RMU_FILE + string "Remote Management Unit (RMU) binary filename" + depends on HAVE_RMU + default "rmu.bin" + help + The filename of the file to use as Remote Management Unit (RMU) + binary in the board directory. + +config RMU_ADDR + hex "Remote Management Unit (RMU) binary location" + depends on HAVE_RMU + default 0xfff00000 + help + The location of the RMU binary is determined by a strap. It must be + put in flash at a location matching the strap-determined base address. + + The default base address of 0xfff00000 indicates that the binary must + be located at offset 0 from the beginning of a 1MB flash device. + +config HAVE_CMC + bool + default HAVE_RMU + +config CMC_FILE + string + depends on HAVE_CMC + default RMU_FILE + +config CMC_ADDR + hex + depends on HAVE_CMC + default RMU_ADDR + +config SYS_CAR_ADDR + hex + default 0x80000000 + +config SYS_CAR_SIZE + hex + default 0x8000 + +endif diff --git a/arch/x86/cpu/quark/Makefile b/arch/x86/cpu/quark/Makefile new file mode 100644 index 0000000..168c1e6 --- /dev/null +++ b/arch/x86/cpu/quark/Makefile @@ -0,0 +1,8 @@ +# +# Copyright (C) 2015, Bin Meng bmeng.cn@gmail.com +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += car.o dram.o msg_port.o quark.o +obj-$(CONFIG_PCI) += pci.o diff --git a/arch/x86/cpu/quark/dram.c b/arch/x86/cpu/quark/dram.c new file mode 100644 index 0000000..fbdc3cd --- /dev/null +++ b/arch/x86/cpu/quark/dram.c @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2015, Bin Meng bmeng.cn@gmail.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/post.h> +#include <asm/arch/quark.h> + +DECLARE_GLOBAL_DATA_PTR; + +int dram_init(void) +{ + /* hardcode the DRAM size for now */ + gd->ram_size = DRAM_MAX_SIZE; + post_code(POST_DRAM); + + return 0; +} + +void dram_init_banksize(void) +{ + gd->bd->bi_dram[0].start = 0; + gd->bd->bi_dram[0].size = gd->ram_size; +} + +/* + * This function looks for the highest region of memory lower than 4GB which + * has enough space for U-Boot where U-Boot is aligned on a page boundary. + * It overrides the default implementation found elsewhere which simply + * picks the end of ram, wherever that may be. The location of the stack, + * the relocation address, and how far U-Boot is moved by relocation are + * set in the global data structure. + */ +ulong board_get_usable_ram_top(ulong total_size) +{ + return gd->ram_size; +} diff --git a/arch/x86/cpu/quark/pci.c b/arch/x86/cpu/quark/pci.c new file mode 100644 index 0000000..354e15a --- /dev/null +++ b/arch/x86/cpu/quark/pci.c @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2015, Bin Meng bmeng.cn@gmail.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <pci.h> +#include <asm/pci.h> +#include <asm/arch/device.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, + PCI_REGION_MEM | PCI_REGION_SYS_MEMORY); + + hose->region_count = 4; +} + +int board_pci_post_scan(struct pci_controller *hose) +{ + return 0; +} + +int pci_skip_dev(struct pci_controller *hose, pci_dev_t dev) +{ + /* + * TODO: + * + * For some unknown reason, the PCI enumeration process hangs + * when it scans to the PCIe root port 0 (D23:F0) & 1 (D23:F1). + * + * For now we just skip these two devices, and this needs to + * be revisited later. + */ + if (dev == QUARK_HOST_BRIDGE || + dev == QUARK_PCIE0 || dev == QUARK_PCIE1) { + return 1; + } + + return 0; +} diff --git a/arch/x86/cpu/quark/quark.c b/arch/x86/cpu/quark/quark.c new file mode 100644 index 0000000..47ba152 --- /dev/null +++ b/arch/x86/cpu/quark/quark.c @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2015, Bin Meng bmeng.cn@gmail.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/pci.h> +#include <asm/post.h> +#include <asm/processor.h> + +int arch_cpu_init(void) +{ + struct pci_controller *hose; + int ret; + + post_code(POST_CPU_INIT); +#ifdef CONFIG_SYS_X86_TSC_TIMER + timer_set_base(rdtsc()); +#endif + + ret = x86_cpu_init_f(); + if (ret) + return ret; + + ret = pci_early_init_hose(&hose); + if (ret) + return ret; + + return 0; +} + +int print_cpuinfo(void) +{ + post_code(POST_CPU_INFO); + return default_print_cpuinfo(); +} + +void reset_cpu(ulong addr) +{ + /* cold reset */ + outb(0x08, PORT_RESET); +} diff --git a/arch/x86/include/asm/arch-quark/gpio.h b/arch/x86/include/asm/arch-quark/gpio.h new file mode 100644 index 0000000..ca8cba4 --- /dev/null +++ b/arch/x86/include/asm/arch-quark/gpio.h @@ -0,0 +1,13 @@ +/* + * Copyright (C) 2015, Bin Meng bmeng.cn@gmail.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _X86_ARCH_GPIO_H_ +#define _X86_ARCH_GPIO_H_ + +/* Where in config space is the register that points to the GPIO registers? */ +#define PCI_CFG_GPIOBASE 0x44 + +#endif /* _X86_ARCH_GPIO_H_ */

Hi Bin,
On 28 January 2015 at 07:20, Bin Meng bmeng.cn@gmail.com wrote:
Add minimum codes to support Intel Quark SoC. DRAM initialization is not ready yet so a hardcoded gd->ram_size is assigned.
Signed-off-by: Bin Meng bmeng.cn@gmail.com
arch/x86/cpu/quark/Kconfig | 63 ++++++++++++++++++++++++++++++ arch/x86/cpu/quark/Makefile | 8 ++++ arch/x86/cpu/quark/dram.c | 39 +++++++++++++++++++ arch/x86/cpu/quark/pci.c | 70 ++++++++++++++++++++++++++++++++++ arch/x86/cpu/quark/quark.c | 44 +++++++++++++++++++++ arch/x86/include/asm/arch-quark/gpio.h | 13 +++++++ 6 files changed, 237 insertions(+) create mode 100644 arch/x86/cpu/quark/Kconfig create mode 100644 arch/x86/cpu/quark/Makefile create mode 100644 arch/x86/cpu/quark/dram.c create mode 100644 arch/x86/cpu/quark/pci.c create mode 100644 arch/x86/cpu/quark/quark.c create mode 100644 arch/x86/include/asm/arch-quark/gpio.h
diff --git a/arch/x86/cpu/quark/Kconfig b/arch/x86/cpu/quark/Kconfig new file mode 100644 index 0000000..a71cc6c --- /dev/null +++ b/arch/x86/cpu/quark/Kconfig @@ -0,0 +1,63 @@ +# +# Copyright (C) 2015, Bin Meng bmeng.cn@gmail.com +# +# SPDX-License-Identifier: GPL-2.0+ +#
+config INTEL_QUARK
bool
select HAVE_RMU
+if INTEL_QUARK
+config HAVE_RMU
bool "Add a Remote Management Unit (RMU) binary"
help
Select this option to add a Remote Management Unit (RMU) binary
to the resulting U-Boot image. It is a data block (up to 64K) of
machine specific code which must be put in the flash for the RMU
machine-specific
within the Quark SoC processor to access when powered up before
system BIOS is executed.
So does this happen before the reset vector?!
+config RMU_FILE
string "Remote Management Unit (RMU) binary filename"
depends on HAVE_RMU
default "rmu.bin"
help
The filename of the file to use as Remote Management Unit (RMU)
binary in the board directory.
+config RMU_ADDR
hex "Remote Management Unit (RMU) binary location"
depends on HAVE_RMU
default 0xfff00000
help
The location of the RMU binary is determined by a strap. It must be
put in flash at a location matching the strap-determined base address.
The default base address of 0xfff00000 indicates that the binary must
be located at offset 0 from the beginning of a 1MB flash device.
+config HAVE_CMC
bool
default HAVE_RMU
+config CMC_FILE
string
depends on HAVE_CMC
default RMU_FILE
+config CMC_ADDR
hex
depends on HAVE_CMC
default RMU_ADDR
+config SYS_CAR_ADDR
hex
default 0x80000000
+config SYS_CAR_SIZE
hex
default 0x8000
+endif diff --git a/arch/x86/cpu/quark/Makefile b/arch/x86/cpu/quark/Makefile new file mode 100644 index 0000000..168c1e6 --- /dev/null +++ b/arch/x86/cpu/quark/Makefile @@ -0,0 +1,8 @@ +# +# Copyright (C) 2015, Bin Meng bmeng.cn@gmail.com +# +# SPDX-License-Identifier: GPL-2.0+ +#
+obj-y += car.o dram.o msg_port.o quark.o +obj-$(CONFIG_PCI) += pci.o diff --git a/arch/x86/cpu/quark/dram.c b/arch/x86/cpu/quark/dram.c new file mode 100644 index 0000000..fbdc3cd --- /dev/null +++ b/arch/x86/cpu/quark/dram.c @@ -0,0 +1,39 @@ +/*
- Copyright (C) 2015, Bin Meng bmeng.cn@gmail.com
- SPDX-License-Identifier: GPL-2.0+
- */
+#include <common.h> +#include <asm/post.h> +#include <asm/arch/quark.h>
+DECLARE_GLOBAL_DATA_PTR;
+int dram_init(void) +{
/* hardcode the DRAM size for now */
gd->ram_size = DRAM_MAX_SIZE;
post_code(POST_DRAM);
return 0;
+}
+void dram_init_banksize(void) +{
gd->bd->bi_dram[0].start = 0;
gd->bd->bi_dram[0].size = gd->ram_size;
+}
+/*
- This function looks for the highest region of memory lower than 4GB which
- has enough space for U-Boot where U-Boot is aligned on a page boundary.
- It overrides the default implementation found elsewhere which simply
- picks the end of ram, wherever that may be. The location of the stack,
- the relocation address, and how far U-Boot is moved by relocation are
- set in the global data structure.
- */
+ulong board_get_usable_ram_top(ulong total_size) +{
return gd->ram_size;
+} diff --git a/arch/x86/cpu/quark/pci.c b/arch/x86/cpu/quark/pci.c new file mode 100644 index 0000000..354e15a --- /dev/null +++ b/arch/x86/cpu/quark/pci.c @@ -0,0 +1,70 @@ +/*
- Copyright (C) 2015, Bin Meng bmeng.cn@gmail.com
- SPDX-License-Identifier: GPL-2.0+
- */
+#include <common.h> +#include <pci.h> +#include <asm/pci.h> +#include <asm/arch/device.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,
PCI_REGION_MEM | PCI_REGION_SYS_MEMORY);
hose->region_count = 4;
+}
+int board_pci_post_scan(struct pci_controller *hose) +{
return 0;
+}
+int pci_skip_dev(struct pci_controller *hose, pci_dev_t dev) +{
/*
* TODO:
*
* For some unknown reason, the PCI enumeration process hangs
* when it scans to the PCIe root port 0 (D23:F0) & 1 (D23:F1).
*
* For now we just skip these two devices, and this needs to
* be revisited later.
*/
if (dev == QUARK_HOST_BRIDGE ||
dev == QUARK_PCIE0 || dev == QUARK_PCIE1) {
return 1;
BTW I saw a similar thing on Minnowboard Max.
}
return 0;
+} diff --git a/arch/x86/cpu/quark/quark.c b/arch/x86/cpu/quark/quark.c new file mode 100644 index 0000000..47ba152 --- /dev/null +++ b/arch/x86/cpu/quark/quark.c @@ -0,0 +1,44 @@ +/*
- Copyright (C) 2015, Bin Meng bmeng.cn@gmail.com
- SPDX-License-Identifier: GPL-2.0+
- */
+#include <common.h> +#include <asm/io.h> +#include <asm/pci.h> +#include <asm/post.h> +#include <asm/processor.h>
+int arch_cpu_init(void) +{
struct pci_controller *hose;
int ret;
post_code(POST_CPU_INIT);
+#ifdef CONFIG_SYS_X86_TSC_TIMER
timer_set_base(rdtsc());
+#endif
ret = x86_cpu_init_f();
if (ret)
return ret;
ret = pci_early_init_hose(&hose);
if (ret)
return ret;
return 0;
+}
+int print_cpuinfo(void) +{
post_code(POST_CPU_INFO);
return default_print_cpuinfo();
+}
+void reset_cpu(ulong addr) +{
/* cold reset */
outb(0x08, PORT_RESET);
+} diff --git a/arch/x86/include/asm/arch-quark/gpio.h b/arch/x86/include/asm/arch-quark/gpio.h new file mode 100644 index 0000000..ca8cba4 --- /dev/null +++ b/arch/x86/include/asm/arch-quark/gpio.h @@ -0,0 +1,13 @@ +/*
- Copyright (C) 2015, Bin Meng bmeng.cn@gmail.com
- SPDX-License-Identifier: GPL-2.0+
- */
+#ifndef _X86_ARCH_GPIO_H_ +#define _X86_ARCH_GPIO_H_
+/* Where in config space is the register that points to the GPIO registers? */ +#define PCI_CFG_GPIOBASE 0x44
Should this be in device tree?
+#endif /* _X86_ARCH_GPIO_H_ */
1.8.2.1
Looks good to me.
Regards, Simon

Hi Simon,
On Thu, Jan 29, 2015 at 2:05 AM, Simon Glass sjg@chromium.org wrote:
Hi Bin,
On 28 January 2015 at 07:20, Bin Meng bmeng.cn@gmail.com wrote:
Add minimum codes to support Intel Quark SoC. DRAM initialization is not ready yet so a hardcoded gd->ram_size is assigned.
Signed-off-by: Bin Meng bmeng.cn@gmail.com
arch/x86/cpu/quark/Kconfig | 63 ++++++++++++++++++++++++++++++ arch/x86/cpu/quark/Makefile | 8 ++++ arch/x86/cpu/quark/dram.c | 39 +++++++++++++++++++ arch/x86/cpu/quark/pci.c | 70 ++++++++++++++++++++++++++++++++++ arch/x86/cpu/quark/quark.c | 44 +++++++++++++++++++++ arch/x86/include/asm/arch-quark/gpio.h | 13 +++++++ 6 files changed, 237 insertions(+) create mode 100644 arch/x86/cpu/quark/Kconfig create mode 100644 arch/x86/cpu/quark/Makefile create mode 100644 arch/x86/cpu/quark/dram.c create mode 100644 arch/x86/cpu/quark/pci.c create mode 100644 arch/x86/cpu/quark/quark.c create mode 100644 arch/x86/include/asm/arch-quark/gpio.h
diff --git a/arch/x86/cpu/quark/Kconfig b/arch/x86/cpu/quark/Kconfig new file mode 100644 index 0000000..a71cc6c --- /dev/null +++ b/arch/x86/cpu/quark/Kconfig @@ -0,0 +1,63 @@ +# +# Copyright (C) 2015, Bin Meng bmeng.cn@gmail.com +# +# SPDX-License-Identifier: GPL-2.0+ +#
+config INTEL_QUARK
bool
select HAVE_RMU
+if INTEL_QUARK
+config HAVE_RMU
bool "Add a Remote Management Unit (RMU) binary"
help
Select this option to add a Remote Management Unit (RMU) binary
to the resulting U-Boot image. It is a data block (up to 64K) of
machine specific code which must be put in the flash for the RMU
machine-specific
OK.
within the Quark SoC processor to access when powered up before
system BIOS is executed.
So does this happen before the reset vector?!
Looks like so. This is something like Tunnel Creek's CMC, as you see below I mapped RMU_xxx to CMC_xxx.
+config RMU_FILE
string "Remote Management Unit (RMU) binary filename"
depends on HAVE_RMU
default "rmu.bin"
help
The filename of the file to use as Remote Management Unit (RMU)
binary in the board directory.
+config RMU_ADDR
hex "Remote Management Unit (RMU) binary location"
depends on HAVE_RMU
default 0xfff00000
help
The location of the RMU binary is determined by a strap. It must be
put in flash at a location matching the strap-determined base address.
The default base address of 0xfff00000 indicates that the binary must
be located at offset 0 from the beginning of a 1MB flash device.
+config HAVE_CMC
bool
default HAVE_RMU
+config CMC_FILE
string
depends on HAVE_CMC
default RMU_FILE
+config CMC_ADDR
hex
depends on HAVE_CMC
default RMU_ADDR
+config SYS_CAR_ADDR
hex
default 0x80000000
+config SYS_CAR_SIZE
hex
default 0x8000
+endif diff --git a/arch/x86/cpu/quark/Makefile b/arch/x86/cpu/quark/Makefile new file mode 100644 index 0000000..168c1e6 --- /dev/null +++ b/arch/x86/cpu/quark/Makefile @@ -0,0 +1,8 @@ +# +# Copyright (C) 2015, Bin Meng bmeng.cn@gmail.com +# +# SPDX-License-Identifier: GPL-2.0+ +#
+obj-y += car.o dram.o msg_port.o quark.o +obj-$(CONFIG_PCI) += pci.o diff --git a/arch/x86/cpu/quark/dram.c b/arch/x86/cpu/quark/dram.c new file mode 100644 index 0000000..fbdc3cd --- /dev/null +++ b/arch/x86/cpu/quark/dram.c @@ -0,0 +1,39 @@ +/*
- Copyright (C) 2015, Bin Meng bmeng.cn@gmail.com
- SPDX-License-Identifier: GPL-2.0+
- */
+#include <common.h> +#include <asm/post.h> +#include <asm/arch/quark.h>
+DECLARE_GLOBAL_DATA_PTR;
+int dram_init(void) +{
/* hardcode the DRAM size for now */
gd->ram_size = DRAM_MAX_SIZE;
post_code(POST_DRAM);
return 0;
+}
+void dram_init_banksize(void) +{
gd->bd->bi_dram[0].start = 0;
gd->bd->bi_dram[0].size = gd->ram_size;
+}
+/*
- This function looks for the highest region of memory lower than 4GB which
- has enough space for U-Boot where U-Boot is aligned on a page boundary.
- It overrides the default implementation found elsewhere which simply
- picks the end of ram, wherever that may be. The location of the stack,
- the relocation address, and how far U-Boot is moved by relocation are
- set in the global data structure.
- */
+ulong board_get_usable_ram_top(ulong total_size) +{
return gd->ram_size;
+} diff --git a/arch/x86/cpu/quark/pci.c b/arch/x86/cpu/quark/pci.c new file mode 100644 index 0000000..354e15a --- /dev/null +++ b/arch/x86/cpu/quark/pci.c @@ -0,0 +1,70 @@ +/*
- Copyright (C) 2015, Bin Meng bmeng.cn@gmail.com
- SPDX-License-Identifier: GPL-2.0+
- */
+#include <common.h> +#include <pci.h> +#include <asm/pci.h> +#include <asm/arch/device.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,
PCI_REGION_MEM | PCI_REGION_SYS_MEMORY);
hose->region_count = 4;
+}
+int board_pci_post_scan(struct pci_controller *hose) +{
return 0;
+}
+int pci_skip_dev(struct pci_controller *hose, pci_dev_t dev) +{
/*
* TODO:
*
* For some unknown reason, the PCI enumeration process hangs
* when it scans to the PCIe root port 0 (D23:F0) & 1 (D23:F1).
*
* For now we just skip these two devices, and this needs to
* be revisited later.
*/
if (dev == QUARK_HOST_BRIDGE ||
dev == QUARK_PCIE0 || dev == QUARK_PCIE1) {
return 1;
BTW I saw a similar thing on Minnowboard Max.
I have not traced this any further. Maybe it is because there is nothing connected from any of the PCIe port? I know Freescale PCIe controller has such limitation that if there is nothing connected, accessing to their register will hang, but Freescale provides a register for software to query PCIe link training status which is nice.
}
return 0;
+} diff --git a/arch/x86/cpu/quark/quark.c b/arch/x86/cpu/quark/quark.c new file mode 100644 index 0000000..47ba152 --- /dev/null +++ b/arch/x86/cpu/quark/quark.c @@ -0,0 +1,44 @@ +/*
- Copyright (C) 2015, Bin Meng bmeng.cn@gmail.com
- SPDX-License-Identifier: GPL-2.0+
- */
+#include <common.h> +#include <asm/io.h> +#include <asm/pci.h> +#include <asm/post.h> +#include <asm/processor.h>
+int arch_cpu_init(void) +{
struct pci_controller *hose;
int ret;
post_code(POST_CPU_INIT);
+#ifdef CONFIG_SYS_X86_TSC_TIMER
timer_set_base(rdtsc());
+#endif
ret = x86_cpu_init_f();
if (ret)
return ret;
ret = pci_early_init_hose(&hose);
if (ret)
return ret;
return 0;
+}
+int print_cpuinfo(void) +{
post_code(POST_CPU_INFO);
return default_print_cpuinfo();
+}
+void reset_cpu(ulong addr) +{
/* cold reset */
outb(0x08, PORT_RESET);
+} diff --git a/arch/x86/include/asm/arch-quark/gpio.h b/arch/x86/include/asm/arch-quark/gpio.h new file mode 100644 index 0000000..ca8cba4 --- /dev/null +++ b/arch/x86/include/asm/arch-quark/gpio.h @@ -0,0 +1,13 @@ +/*
- Copyright (C) 2015, Bin Meng bmeng.cn@gmail.com
- SPDX-License-Identifier: GPL-2.0+
- */
+#ifndef _X86_ARCH_GPIO_H_ +#define _X86_ARCH_GPIO_H_
+/* Where in config space is the register that points to the GPIO registers? */ +#define PCI_CFG_GPIOBASE 0x44
Should this be in device tree?
I think so, but I think we can leave this change later, just like the SPI controller driver?
+#endif /* _X86_ARCH_GPIO_H_ */
1.8.2.1
Looks good to me.
Regards, Bin

Hi Bin,
On 28 January 2015 at 19:17, Bin Meng bmeng.cn@gmail.com wrote:
Hi Simon,
On Thu, Jan 29, 2015 at 2:05 AM, Simon Glass sjg@chromium.org wrote:
Hi Bin,
On 28 January 2015 at 07:20, Bin Meng bmeng.cn@gmail.com wrote:
Add minimum codes to support Intel Quark SoC. DRAM initialization is not ready yet so a hardcoded gd->ram_size is assigned.
Signed-off-by: Bin Meng bmeng.cn@gmail.com
arch/x86/cpu/quark/Kconfig | 63 ++++++++++++++++++++++++++++++ arch/x86/cpu/quark/Makefile | 8 ++++ arch/x86/cpu/quark/dram.c | 39 +++++++++++++++++++ arch/x86/cpu/quark/pci.c | 70 ++++++++++++++++++++++++++++++++++ arch/x86/cpu/quark/quark.c | 44 +++++++++++++++++++++ arch/x86/include/asm/arch-quark/gpio.h | 13 +++++++ 6 files changed, 237 insertions(+) create mode 100644 arch/x86/cpu/quark/Kconfig create mode 100644 arch/x86/cpu/quark/Makefile create mode 100644 arch/x86/cpu/quark/dram.c create mode 100644 arch/x86/cpu/quark/pci.c create mode 100644 arch/x86/cpu/quark/quark.c create mode 100644 arch/x86/include/asm/arch-quark/gpio.h
diff --git a/arch/x86/cpu/quark/Kconfig b/arch/x86/cpu/quark/Kconfig new file mode 100644 index 0000000..a71cc6c --- /dev/null +++ b/arch/x86/cpu/quark/Kconfig @@ -0,0 +1,63 @@ +# +# Copyright (C) 2015, Bin Meng bmeng.cn@gmail.com +# +# SPDX-License-Identifier: GPL-2.0+ +#
+config INTEL_QUARK
bool
select HAVE_RMU
+if INTEL_QUARK
+config HAVE_RMU
bool "Add a Remote Management Unit (RMU) binary"
help
Select this option to add a Remote Management Unit (RMU) binary
to the resulting U-Boot image. It is a data block (up to 64K) of
machine specific code which must be put in the flash for the RMU
machine-specific
OK.
within the Quark SoC processor to access when powered up before
system BIOS is executed.
So does this happen before the reset vector?!
Looks like so. This is something like Tunnel Creek's CMC, as you see below I mapped RMU_xxx to CMC_xxx.
+config RMU_FILE
string "Remote Management Unit (RMU) binary filename"
depends on HAVE_RMU
default "rmu.bin"
help
The filename of the file to use as Remote Management Unit (RMU)
binary in the board directory.
+config RMU_ADDR
hex "Remote Management Unit (RMU) binary location"
depends on HAVE_RMU
default 0xfff00000
help
The location of the RMU binary is determined by a strap. It must be
put in flash at a location matching the strap-determined base address.
The default base address of 0xfff00000 indicates that the binary must
be located at offset 0 from the beginning of a 1MB flash device.
+config HAVE_CMC
bool
default HAVE_RMU
+config CMC_FILE
string
depends on HAVE_CMC
default RMU_FILE
+config CMC_ADDR
hex
depends on HAVE_CMC
default RMU_ADDR
+config SYS_CAR_ADDR
hex
default 0x80000000
+config SYS_CAR_SIZE
hex
default 0x8000
+endif diff --git a/arch/x86/cpu/quark/Makefile b/arch/x86/cpu/quark/Makefile new file mode 100644 index 0000000..168c1e6 --- /dev/null +++ b/arch/x86/cpu/quark/Makefile @@ -0,0 +1,8 @@ +# +# Copyright (C) 2015, Bin Meng bmeng.cn@gmail.com +# +# SPDX-License-Identifier: GPL-2.0+ +#
+obj-y += car.o dram.o msg_port.o quark.o +obj-$(CONFIG_PCI) += pci.o diff --git a/arch/x86/cpu/quark/dram.c b/arch/x86/cpu/quark/dram.c new file mode 100644 index 0000000..fbdc3cd --- /dev/null +++ b/arch/x86/cpu/quark/dram.c @@ -0,0 +1,39 @@ +/*
- Copyright (C) 2015, Bin Meng bmeng.cn@gmail.com
- SPDX-License-Identifier: GPL-2.0+
- */
+#include <common.h> +#include <asm/post.h> +#include <asm/arch/quark.h>
+DECLARE_GLOBAL_DATA_PTR;
+int dram_init(void) +{
/* hardcode the DRAM size for now */
gd->ram_size = DRAM_MAX_SIZE;
post_code(POST_DRAM);
return 0;
+}
+void dram_init_banksize(void) +{
gd->bd->bi_dram[0].start = 0;
gd->bd->bi_dram[0].size = gd->ram_size;
+}
+/*
- This function looks for the highest region of memory lower than 4GB which
- has enough space for U-Boot where U-Boot is aligned on a page boundary.
- It overrides the default implementation found elsewhere which simply
- picks the end of ram, wherever that may be. The location of the stack,
- the relocation address, and how far U-Boot is moved by relocation are
- set in the global data structure.
- */
+ulong board_get_usable_ram_top(ulong total_size) +{
return gd->ram_size;
+} diff --git a/arch/x86/cpu/quark/pci.c b/arch/x86/cpu/quark/pci.c new file mode 100644 index 0000000..354e15a --- /dev/null +++ b/arch/x86/cpu/quark/pci.c @@ -0,0 +1,70 @@ +/*
- Copyright (C) 2015, Bin Meng bmeng.cn@gmail.com
- SPDX-License-Identifier: GPL-2.0+
- */
+#include <common.h> +#include <pci.h> +#include <asm/pci.h> +#include <asm/arch/device.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,
PCI_REGION_MEM | PCI_REGION_SYS_MEMORY);
hose->region_count = 4;
+}
+int board_pci_post_scan(struct pci_controller *hose) +{
return 0;
+}
+int pci_skip_dev(struct pci_controller *hose, pci_dev_t dev) +{
/*
* TODO:
*
* For some unknown reason, the PCI enumeration process hangs
* when it scans to the PCIe root port 0 (D23:F0) & 1 (D23:F1).
*
* For now we just skip these two devices, and this needs to
* be revisited later.
*/
if (dev == QUARK_HOST_BRIDGE ||
dev == QUARK_PCIE0 || dev == QUARK_PCIE1) {
return 1;
BTW I saw a similar thing on Minnowboard Max.
I have not traced this any further. Maybe it is because there is nothing connected from any of the PCIe port? I know Freescale PCIe controller has such limitation that if there is nothing connected, accessing to their register will hang, but Freescale provides a register for software to query PCIe link training status which is nice.
Maybe. But it seems bad that it doesn't respond.
}
return 0;
+} diff --git a/arch/x86/cpu/quark/quark.c b/arch/x86/cpu/quark/quark.c new file mode 100644 index 0000000..47ba152 --- /dev/null +++ b/arch/x86/cpu/quark/quark.c @@ -0,0 +1,44 @@ +/*
- Copyright (C) 2015, Bin Meng bmeng.cn@gmail.com
- SPDX-License-Identifier: GPL-2.0+
- */
+#include <common.h> +#include <asm/io.h> +#include <asm/pci.h> +#include <asm/post.h> +#include <asm/processor.h>
+int arch_cpu_init(void) +{
struct pci_controller *hose;
int ret;
post_code(POST_CPU_INIT);
+#ifdef CONFIG_SYS_X86_TSC_TIMER
timer_set_base(rdtsc());
+#endif
ret = x86_cpu_init_f();
if (ret)
return ret;
ret = pci_early_init_hose(&hose);
if (ret)
return ret;
return 0;
+}
+int print_cpuinfo(void) +{
post_code(POST_CPU_INFO);
return default_print_cpuinfo();
+}
+void reset_cpu(ulong addr) +{
/* cold reset */
outb(0x08, PORT_RESET);
+} diff --git a/arch/x86/include/asm/arch-quark/gpio.h b/arch/x86/include/asm/arch-quark/gpio.h new file mode 100644 index 0000000..ca8cba4 --- /dev/null +++ b/arch/x86/include/asm/arch-quark/gpio.h @@ -0,0 +1,13 @@ +/*
- Copyright (C) 2015, Bin Meng bmeng.cn@gmail.com
- SPDX-License-Identifier: GPL-2.0+
- */
+#ifndef _X86_ARCH_GPIO_H_ +#define _X86_ARCH_GPIO_H_
+/* Where in config space is the register that points to the GPIO registers? */ +#define PCI_CFG_GPIOBASE 0x44
Should this be in device tree?
I think so, but I think we can leave this change later, just like the SPI controller driver?
Yes we don't need to do everything at once. The GPIO side is a bit broken as you probably saw. I'm really not happen with how I have implemented it. We should be able to describe the pin mappings in the device tree.
Regards, Simon

New board/intel/galileo board directory with minimum codes, plus board dts, defconfig and configuration files.
Signed-off-by: Bin Meng bmeng.cn@gmail.com ---
arch/x86/dts/Makefile | 3 ++- arch/x86/dts/galileo.dts | 43 +++++++++++++++++++++++++++++++++ board/intel/galileo/Kconfig | 21 ++++++++++++++++ board/intel/galileo/MAINTAINERS | 6 +++++ board/intel/galileo/Makefile | 7 ++++++ board/intel/galileo/galileo.c | 19 +++++++++++++++ board/intel/galileo/start.S | 9 +++++++ configs/galileo_defconfig | 6 +++++ include/configs/galileo.h | 53 +++++++++++++++++++++++++++++++++++++++++ 9 files changed, 166 insertions(+), 1 deletion(-) create mode 100644 arch/x86/dts/galileo.dts create mode 100644 board/intel/galileo/Kconfig create mode 100644 board/intel/galileo/MAINTAINERS create mode 100644 board/intel/galileo/Makefile create mode 100644 board/intel/galileo/galileo.c create mode 100644 board/intel/galileo/start.S create mode 100644 configs/galileo_defconfig create mode 100644 include/configs/galileo.h
diff --git a/arch/x86/dts/Makefile b/arch/x86/dts/Makefile index 97ed884..a470966 100644 --- a/arch/x86/dts/Makefile +++ b/arch/x86/dts/Makefile @@ -1,5 +1,6 @@ dtb-y += chromebook_link.dtb \ - crownbay.dtb + crownbay.dtb \ + galileo.dtb
targets += $(dtb-y)
diff --git a/arch/x86/dts/galileo.dts b/arch/x86/dts/galileo.dts new file mode 100644 index 0000000..14a19c3 --- /dev/null +++ b/arch/x86/dts/galileo.dts @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2015, Bin Meng bmeng.cn@gmail.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/dts-v1/; + +/include/ "skeleton.dtsi" + +/ { + model = "Intel Galileo"; + compatible = "intel,galileo", "intel,quark"; + + config { + silent_console = <0>; + }; + + chosen { + stdout-path = &pciuart0; + }; + + pci { + #address-cells = <3>; + #size-cells = <2>; + compatible = "intel,pci"; + device_type = "pci"; + + pciuart0: uart@14,5 { + compatible = "pci8086,0936.00", + "pci8086,0936", + "pciclass,070002", + "pciclass,0700", + "x86-uart"; + reg = <0x0000a500 0x0 0x0 0x0 0x0 + 0x0200a510 0x0 0x0 0x0 0x0>; + reg-shift = <2>; + clock-frequency = <44236800>; + current-speed = <115200>; + }; + }; + +}; diff --git a/board/intel/galileo/Kconfig b/board/intel/galileo/Kconfig new file mode 100644 index 0000000..85afbbc --- /dev/null +++ b/board/intel/galileo/Kconfig @@ -0,0 +1,21 @@ +if TARGET_GALILEO + +config SYS_BOARD + default "galileo" + +config SYS_VENDOR + default "intel" + +config SYS_SOC + default "quark" + +config SYS_CONFIG_NAME + default "galileo" + +config BOARD_SPECIFIC_OPTIONS # dummy + def_bool y + select X86_RESET_VECTOR + select INTEL_QUARK + select BOARD_ROMSIZE_KB_1024 + +endif diff --git a/board/intel/galileo/MAINTAINERS b/board/intel/galileo/MAINTAINERS new file mode 100644 index 0000000..dbbc82e --- /dev/null +++ b/board/intel/galileo/MAINTAINERS @@ -0,0 +1,6 @@ +INTEL GALILEO BOARD +M: Bin Meng bmeng.cn@gmail.com +S: Maintained +F: board/intel/galileo/ +F: include/configs/galileo.h +F: configs/galileo_defconfig diff --git a/board/intel/galileo/Makefile b/board/intel/galileo/Makefile new file mode 100644 index 0000000..8356df1 --- /dev/null +++ b/board/intel/galileo/Makefile @@ -0,0 +1,7 @@ +# +# Copyright (C) 2015, Bin Meng bmeng.cn@gmail.com +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += galileo.o start.o diff --git a/board/intel/galileo/galileo.c b/board/intel/galileo/galileo.c new file mode 100644 index 0000000..f2e7468 --- /dev/null +++ b/board/intel/galileo/galileo.c @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2015, Bin Meng bmeng.cn@gmail.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> + +DECLARE_GLOBAL_DATA_PTR; + +int board_early_init_f(void) +{ + return 0; +} + +void setup_pch_gpios(u16 gpiobase, const struct pch_gpio_map *gpio) +{ + return; +} diff --git a/board/intel/galileo/start.S b/board/intel/galileo/start.S new file mode 100644 index 0000000..a71db69 --- /dev/null +++ b/board/intel/galileo/start.S @@ -0,0 +1,9 @@ +/* + * Copyright (C) 2015, Bin Meng bmeng.cn@gmail.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +.globl early_board_init +early_board_init: + jmp early_board_init_ret diff --git a/configs/galileo_defconfig b/configs/galileo_defconfig new file mode 100644 index 0000000..f208651 --- /dev/null +++ b/configs/galileo_defconfig @@ -0,0 +1,6 @@ +CONFIG_SYS_EXTRA_OPTIONS="SYS_TEXT_BASE=0xfff10000" +CONFIG_X86=y +CONFIG_TARGET_GALILEO=y +CONFIG_OF_CONTROL=y +CONFIG_OF_SEPARATE=y +CONFIG_DEFAULT_DEVICE_TREE="galileo" diff --git a/include/configs/galileo.h b/include/configs/galileo.h new file mode 100644 index 0000000..bead2fc --- /dev/null +++ b/include/configs/galileo.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2015, Bin Meng bmeng.cn@gmail.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* + * board/config.h - configuration options, board specific + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +#include <configs/x86-common.h> + +#define CONFIG_SYS_MONITOR_LEN (1 << 20) +#define CONFIG_BOARD_EARLY_INIT_F + +#define CONFIG_NR_DRAM_BANKS 1 + +#define CONFIG_X86_SERIAL + +/* ns16550 UART is memory-mapped in Quark SoC */ +#undef CONFIG_SYS_NS16550_PORT_MAPPED + +#define CONFIG_PCI_MEM_BUS 0x90000000 +#define CONFIG_PCI_MEM_PHYS CONFIG_PCI_MEM_BUS +#define CONFIG_PCI_MEM_SIZE 0x20000000 + +#define CONFIG_PCI_PREF_BUS 0xb0000000 +#define CONFIG_PCI_PREF_PHYS CONFIG_PCI_PREF_BUS +#define CONFIG_PCI_PREF_SIZE 0x20000000 + +#define CONFIG_PCI_IO_BUS 0x2000 +#define CONFIG_PCI_IO_PHYS CONFIG_PCI_IO_BUS +#define CONFIG_PCI_IO_SIZE 0xe000 + +#define CONFIG_SYS_EARLY_PCI_INIT +#define CONFIG_PCI_PNP + +#define CONFIG_STD_DEVICES_SETTINGS "stdin=serial\0" \ + "stdout=serial\0" \ + "stderr=serial\0" + +/* SATA is not supported in Quark SoC */ +#undef CONFIG_SCSI_AHCI +#undef CONFIG_CMD_SCSI + +/* Video is not supported in Quark SoC */ +#undef CONFIG_VIDEO +#undef CONFIG_CFB_CONSOLE + +#endif /* __CONFIG_H */

On 28 January 2015 at 07:20, Bin Meng bmeng.cn@gmail.com wrote:
New board/intel/galileo board directory with minimum codes, plus board dts, defconfig and configuration files.
Signed-off-by: Bin Meng bmeng.cn@gmail.com
arch/x86/dts/Makefile | 3 ++- arch/x86/dts/galileo.dts | 43 +++++++++++++++++++++++++++++++++ board/intel/galileo/Kconfig | 21 ++++++++++++++++ board/intel/galileo/MAINTAINERS | 6 +++++ board/intel/galileo/Makefile | 7 ++++++ board/intel/galileo/galileo.c | 19 +++++++++++++++ board/intel/galileo/start.S | 9 +++++++ configs/galileo_defconfig | 6 +++++ include/configs/galileo.h | 53 +++++++++++++++++++++++++++++++++++++++++ 9 files changed, 166 insertions(+), 1 deletion(-) create mode 100644 arch/x86/dts/galileo.dts create mode 100644 board/intel/galileo/Kconfig create mode 100644 board/intel/galileo/MAINTAINERS create mode 100644 board/intel/galileo/Makefile create mode 100644 board/intel/galileo/galileo.c create mode 100644 board/intel/galileo/start.S create mode 100644 configs/galileo_defconfig create mode 100644 include/configs/galileo.h
diff --git a/arch/x86/dts/Makefile b/arch/x86/dts/Makefile index 97ed884..a470966 100644 --- a/arch/x86/dts/Makefile +++ b/arch/x86/dts/Makefile @@ -1,5 +1,6 @@ dtb-y += chromebook_link.dtb \
crownbay.dtb
crownbay.dtb \
galileo.dtb
targets += $(dtb-y)
diff --git a/arch/x86/dts/galileo.dts b/arch/x86/dts/galileo.dts new file mode 100644 index 0000000..14a19c3 --- /dev/null +++ b/arch/x86/dts/galileo.dts @@ -0,0 +1,43 @@ +/*
- Copyright (C) 2015, Bin Meng bmeng.cn@gmail.com
- SPDX-License-Identifier: GPL-2.0+
- */
+/dts-v1/;
+/include/ "skeleton.dtsi"
+/ {
model = "Intel Galileo";
compatible = "intel,galileo", "intel,quark";
config {
silent_console = <0>;
};
chosen {
stdout-path = &pciuart0;
};
pci {
#address-cells = <3>;
#size-cells = <2>;
compatible = "intel,pci";
device_type = "pci";
pciuart0: uart@14,5 {
compatible = "pci8086,0936.00",
"pci8086,0936",
"pciclass,070002",
"pciclass,0700",
"x86-uart";
reg = <0x0000a500 0x0 0x0 0x0 0x0
0x0200a510 0x0 0x0 0x0 0x0>;
reg-shift = <2>;
clock-frequency = <44236800>;
current-speed = <115200>;
};
};
+}; diff --git a/board/intel/galileo/Kconfig b/board/intel/galileo/Kconfig new file mode 100644 index 0000000..85afbbc --- /dev/null +++ b/board/intel/galileo/Kconfig @@ -0,0 +1,21 @@ +if TARGET_GALILEO
+config SYS_BOARD
default "galileo"
+config SYS_VENDOR
default "intel"
+config SYS_SOC
default "quark"
+config SYS_CONFIG_NAME
default "galileo"
+config BOARD_SPECIFIC_OPTIONS # dummy
def_bool y
select X86_RESET_VECTOR
select INTEL_QUARK
select BOARD_ROMSIZE_KB_1024
+endif diff --git a/board/intel/galileo/MAINTAINERS b/board/intel/galileo/MAINTAINERS new file mode 100644 index 0000000..dbbc82e --- /dev/null +++ b/board/intel/galileo/MAINTAINERS @@ -0,0 +1,6 @@ +INTEL GALILEO BOARD +M: Bin Meng bmeng.cn@gmail.com +S: Maintained +F: board/intel/galileo/ +F: include/configs/galileo.h +F: configs/galileo_defconfig diff --git a/board/intel/galileo/Makefile b/board/intel/galileo/Makefile new file mode 100644 index 0000000..8356df1 --- /dev/null +++ b/board/intel/galileo/Makefile @@ -0,0 +1,7 @@ +# +# Copyright (C) 2015, Bin Meng bmeng.cn@gmail.com +# +# SPDX-License-Identifier: GPL-2.0+ +#
+obj-y += galileo.o start.o diff --git a/board/intel/galileo/galileo.c b/board/intel/galileo/galileo.c new file mode 100644 index 0000000..f2e7468 --- /dev/null +++ b/board/intel/galileo/galileo.c @@ -0,0 +1,19 @@ +/*
- Copyright (C) 2015, Bin Meng bmeng.cn@gmail.com
- SPDX-License-Identifier: GPL-2.0+
- */
+#include <common.h>
+DECLARE_GLOBAL_DATA_PTR;
+int board_early_init_f(void) +{
return 0;
+}
+void setup_pch_gpios(u16 gpiobase, const struct pch_gpio_map *gpio) +{
return;
+} diff --git a/board/intel/galileo/start.S b/board/intel/galileo/start.S new file mode 100644 index 0000000..a71db69 --- /dev/null +++ b/board/intel/galileo/start.S @@ -0,0 +1,9 @@ +/*
- Copyright (C) 2015, Bin Meng bmeng.cn@gmail.com
- SPDX-License-Identifier: GPL-2.0+
- */
+.globl early_board_init +early_board_init:
jmp early_board_init_ret
diff --git a/configs/galileo_defconfig b/configs/galileo_defconfig new file mode 100644 index 0000000..f208651 --- /dev/null +++ b/configs/galileo_defconfig @@ -0,0 +1,6 @@ +CONFIG_SYS_EXTRA_OPTIONS="SYS_TEXT_BASE=0xfff10000" +CONFIG_X86=y +CONFIG_TARGET_GALILEO=y +CONFIG_OF_CONTROL=y +CONFIG_OF_SEPARATE=y +CONFIG_DEFAULT_DEVICE_TREE="galileo" diff --git a/include/configs/galileo.h b/include/configs/galileo.h new file mode 100644 index 0000000..bead2fc --- /dev/null +++ b/include/configs/galileo.h @@ -0,0 +1,53 @@ +/*
- Copyright (C) 2015, Bin Meng bmeng.cn@gmail.com
- SPDX-License-Identifier: GPL-2.0+
- */
+/*
- board/config.h - configuration options, board specific
- */
+#ifndef __CONFIG_H +#define __CONFIG_H
+#include <configs/x86-common.h>
+#define CONFIG_SYS_MONITOR_LEN (1 << 20) +#define CONFIG_BOARD_EARLY_INIT_F
+#define CONFIG_NR_DRAM_BANKS 1
+#define CONFIG_X86_SERIAL
+/* ns16550 UART is memory-mapped in Quark SoC */ +#undef CONFIG_SYS_NS16550_PORT_MAPPED
+#define CONFIG_PCI_MEM_BUS 0x90000000 +#define CONFIG_PCI_MEM_PHYS CONFIG_PCI_MEM_BUS +#define CONFIG_PCI_MEM_SIZE 0x20000000
+#define CONFIG_PCI_PREF_BUS 0xb0000000 +#define CONFIG_PCI_PREF_PHYS CONFIG_PCI_PREF_BUS +#define CONFIG_PCI_PREF_SIZE 0x20000000
+#define CONFIG_PCI_IO_BUS 0x2000 +#define CONFIG_PCI_IO_PHYS CONFIG_PCI_IO_BUS +#define CONFIG_PCI_IO_SIZE 0xe000
+#define CONFIG_SYS_EARLY_PCI_INIT +#define CONFIG_PCI_PNP
+#define CONFIG_STD_DEVICES_SETTINGS "stdin=serial\0" \
"stdout=serial\0" \
"stderr=serial\0"
+/* SATA is not supported in Quark SoC */ +#undef CONFIG_SCSI_AHCI +#undef CONFIG_CMD_SCSI
+/* Video is not supported in Quark SoC */ +#undef CONFIG_VIDEO +#undef CONFIG_CFB_CONSOLE
+#endif /* __CONFIG_H */
1.8.2.1
Reviewed-by: Simon Glass sjg@chromium.org

Make the Intel quark/galileo support avaiable in Kconfig and Makefile. With this patch, we can generate u-boot.rom for Intel galileo board.
Signed-off-by: Bin Meng bmeng.cn@gmail.com
---
arch/x86/Kconfig | 17 +++++++++++++++++ arch/x86/cpu/Makefile | 1 + 2 files changed, 18 insertions(+)
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 90e828a..2e64bc1 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -41,6 +41,19 @@ config TARGET_CROWNBAY Intel Platform Controller Hub EG20T, other system components and peripheral connectors for PCIe/SATA/USB/LAN/SD/UART/Audio/LVDS.
+config TARGET_GALILEO + bool "Support Intel Galileo CRB" + help + This is the Intel Galileo board, which is the first in a family of + Arduino certified development and prototyping boards based on Intel + architecture. It includes an Intel Quark SoC X1000 processor, a 32-bit + single-core, single-thread, Intel Pentium processor instrunction set + architecture (ISA) compatible, operating at speeds up to 400Mhz, + along with 256MB DDR3 memory. It supports a wide range of industry + standard I/O interfaces, including a full-sized mini-PCIe slot, + one 100Mb Ethernet port, a microSD card slot, a USB host port and + a USB client port. + endchoice
config RAMBASE @@ -348,6 +361,8 @@ source "arch/x86/cpu/coreboot/Kconfig"
source "arch/x86/cpu/ivybridge/Kconfig"
+source "arch/x86/cpu/quark/Kconfig" + source "arch/x86/cpu/queensbay/Kconfig"
source "board/coreboot/coreboot/Kconfig" @@ -356,4 +371,6 @@ source "board/google/chromebook_link/Kconfig"
source "board/intel/crownbay/Kconfig"
+source "board/intel/galileo/Kconfig" + endmenu diff --git a/arch/x86/cpu/Makefile b/arch/x86/cpu/Makefile index 62e43c0..2d61af0 100644 --- a/arch/x86/cpu/Makefile +++ b/arch/x86/cpu/Makefile @@ -15,6 +15,7 @@ obj-y += interrupts.o cpu.o call64.o obj-$(CONFIG_SYS_COREBOOT) += coreboot/ obj-$(CONFIG_NORTHBRIDGE_INTEL_SANDYBRIDGE) += ivybridge/ obj-$(CONFIG_NORTHBRIDGE_INTEL_IVYBRIDGE) += ivybridge/ +obj-$(CONFIG_INTEL_QUARK) += quark/ obj-$(CONFIG_INTEL_QUEENSBAY) += queensbay/ obj-y += lapic.o obj-y += mtrr.o

On 28 January 2015 at 07:20, Bin Meng bmeng.cn@gmail.com wrote:
Make the Intel quark/galileo support avaiable in Kconfig and Makefile. With this patch, we can generate u-boot.rom for Intel galileo board.
Signed-off-by: Bin Meng bmeng.cn@gmail.com
arch/x86/Kconfig | 17 +++++++++++++++++ arch/x86/cpu/Makefile | 1 + 2 files changed, 18 insertions(+)
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 90e828a..2e64bc1 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -41,6 +41,19 @@ config TARGET_CROWNBAY Intel Platform Controller Hub EG20T, other system components and peripheral connectors for PCIe/SATA/USB/LAN/SD/UART/Audio/LVDS.
+config TARGET_GALILEO
bool "Support Intel Galileo CRB"
help
This is the Intel Galileo board, which is the first in a family of
Arduino certified development and prototyping boards based on Intel
Arduino-certified
architecture. It includes an Intel Quark SoC X1000 processor, a 32-bit
single-core, single-thread, Intel Pentium processor instrunction set
architecture (ISA) compatible, operating at speeds up to 400Mhz,
along with 256MB DDR3 memory. It supports a wide range of industry
standard I/O interfaces, including a full-sized mini-PCIe slot,
one 100Mb Ethernet port, a microSD card slot, a USB host port and
a USB client port.
endchoice
config RAMBASE @@ -348,6 +361,8 @@ source "arch/x86/cpu/coreboot/Kconfig"
source "arch/x86/cpu/ivybridge/Kconfig"
+source "arch/x86/cpu/quark/Kconfig"
source "arch/x86/cpu/queensbay/Kconfig"
source "board/coreboot/coreboot/Kconfig" @@ -356,4 +371,6 @@ source "board/google/chromebook_link/Kconfig"
source "board/intel/crownbay/Kconfig"
+source "board/intel/galileo/Kconfig"
endmenu diff --git a/arch/x86/cpu/Makefile b/arch/x86/cpu/Makefile index 62e43c0..2d61af0 100644 --- a/arch/x86/cpu/Makefile +++ b/arch/x86/cpu/Makefile @@ -15,6 +15,7 @@ obj-y += interrupts.o cpu.o call64.o obj-$(CONFIG_SYS_COREBOOT) += coreboot/ obj-$(CONFIG_NORTHBRIDGE_INTEL_SANDYBRIDGE) += ivybridge/ obj-$(CONFIG_NORTHBRIDGE_INTEL_IVYBRIDGE) += ivybridge/ +obj-$(CONFIG_INTEL_QUARK) += quark/ obj-$(CONFIG_INTEL_QUEENSBAY) += queensbay/ obj-y += lapic.o obj-y += mtrr.o -- 1.8.2.1
Reviewed-by: Simon Glass <sjg@chromium.org.

Hi Bin,
On 28 January 2015 at 07:19, Bin Meng bmeng.cn@gmail.com wrote:
This series adds the first step of bare support for the Intel Quark SoC support which can be validated on Intel Galileo board.
Intel Quark is a line of 32-bit x86 SoCs by Intel, designed for small size and low power consumption, and targeted at new markets including wearable devices. They are smaller and slower than Atom processors and consume less power. They lack support for SIMD instruction sets (such as MMX and SSE) and only support embedded operating systems. Quark powers the Intel Galileo developer microcontroller board. The CPU instruction set is the same as Pentium (P54C/i586) CPU.
Intel decided to completely publish Quark's hardware specification to software developers, which includes an SoC datasheet, a UEFI Firmware Writer's Guide, and a complete reference source code for the UEFI BIOS which is pre-flahsed on the Galileo board. As of today, the only BIOS for Galileo is the Intel one with UEFI inteface only. There is no CSM support yet in that BIOS, neither any 3rd party BIOS vendor provides support to Quark SoC.
So no binary blobs?
Note there are two generation of Galileo boards, aka gen1 and gen2. Currently the development work is on gen2, but once we get it boot, we can easily add the gen1 board (old version).
With this patch series, the generated u-boot.rom could boot the Intel Galileo board up to fdt relocate, where U-Boot hangs because the DRAM is not initializaed yet. A follow up patch series will be sent soon to add support for Memory Reference Code (MRC).
Note this patch series may need rebase after Simon's Minnowmax support patch series is applied.
You can rebase on x86/minnow-working if you like.
Bin Meng (6): x86: Add header files for Intel Quark SoC defines x86: quark: Add routines to access message bus registers x86: quark: Add Cache-As-RAM initialization x86: Add basic Intel Quark processor support x86: Add basic Intel Galileo board support x86: Enable the Intel quark/galileo build
arch/x86/Kconfig | 17 +++++ arch/x86/cpu/Makefile | 1 + arch/x86/cpu/quark/Kconfig | 63 +++++++++++++++++ arch/x86/cpu/quark/Makefile | 8 +++ arch/x86/cpu/quark/car.S | 105 +++++++++++++++++++++++++++++ arch/x86/cpu/quark/dram.c | 39 +++++++++++ arch/x86/cpu/quark/msg_port.c | 76 +++++++++++++++++++++ arch/x86/cpu/quark/pci.c | 70 +++++++++++++++++++ arch/x86/cpu/quark/quark.c | 44 ++++++++++++ arch/x86/dts/Makefile | 3 +- arch/x86/dts/galileo.dts | 43 ++++++++++++ arch/x86/include/asm/arch-quark/device.h | 28 ++++++++ arch/x86/include/asm/arch-quark/gpio.h | 13 ++++ arch/x86/include/asm/arch-quark/msg_port.h | 93 +++++++++++++++++++++++++ arch/x86/include/asm/arch-quark/quark.h | 57 ++++++++++++++++ board/intel/galileo/Kconfig | 21 ++++++ board/intel/galileo/MAINTAINERS | 6 ++ board/intel/galileo/Makefile | 7 ++ board/intel/galileo/galileo.c | 19 ++++++ board/intel/galileo/start.S | 9 +++ configs/galileo_defconfig | 6 ++ include/configs/galileo.h | 53 +++++++++++++++ 22 files changed, 780 insertions(+), 1 deletion(-) create mode 100644 arch/x86/cpu/quark/Kconfig create mode 100644 arch/x86/cpu/quark/Makefile create mode 100644 arch/x86/cpu/quark/car.S create mode 100644 arch/x86/cpu/quark/dram.c create mode 100644 arch/x86/cpu/quark/msg_port.c create mode 100644 arch/x86/cpu/quark/pci.c create mode 100644 arch/x86/cpu/quark/quark.c create mode 100644 arch/x86/dts/galileo.dts create mode 100644 arch/x86/include/asm/arch-quark/device.h create mode 100644 arch/x86/include/asm/arch-quark/gpio.h create mode 100644 arch/x86/include/asm/arch-quark/msg_port.h create mode 100644 arch/x86/include/asm/arch-quark/quark.h create mode 100644 board/intel/galileo/Kconfig create mode 100644 board/intel/galileo/MAINTAINERS create mode 100644 board/intel/galileo/Makefile create mode 100644 board/intel/galileo/galileo.c create mode 100644 board/intel/galileo/start.S create mode 100644 configs/galileo_defconfig create mode 100644 include/configs/galileo.h
-- 1.8.2.1
Regards, Simon

Hi Simon,
On Thu, Jan 29, 2015 at 2:05 AM, Simon Glass sjg@chromium.org wrote:
Hi Bin,
On 28 January 2015 at 07:19, Bin Meng bmeng.cn@gmail.com wrote:
This series adds the first step of bare support for the Intel Quark SoC support which can be validated on Intel Galileo board.
Intel Quark is a line of 32-bit x86 SoCs by Intel, designed for small size and low power consumption, and targeted at new markets including wearable devices. They are smaller and slower than Atom processors and consume less power. They lack support for SIMD instruction sets (such as MMX and SSE) and only support embedded operating systems. Quark powers the Intel Galileo developer microcontroller board. The CPU instruction set is the same as Pentium (P54C/i586) CPU.
Intel decided to completely publish Quark's hardware specification to software developers, which includes an SoC datasheet, a UEFI Firmware Writer's Guide, and a complete reference source code for the UEFI BIOS which is pre-flahsed on the Galileo board. As of today, the only BIOS for Galileo is the Intel one with UEFI inteface only. There is no CSM support yet in that BIOS, neither any 3rd party BIOS vendor provides support to Quark SoC.
So no binary blobs?
Ah, forget to mention, only one binary blob (exactly 8KiB) is needed which is rmu.bin for Remote Management Unit. Not like FSP, U-Boot will not call into the binary. The binary is needed by the Quark SoC itself. Everything on Quark will have its source codes including MRC.
Note there are two generation of Galileo boards, aka gen1 and gen2. Currently the development work is on gen2, but once we get it boot, we can easily add the gen1 board (old version).
With this patch series, the generated u-boot.rom could boot the Intel Galileo board up to fdt relocate, where U-Boot hangs because the DRAM is not initializaed yet. A follow up patch series will be sent soon to add support for Memory Reference Code (MRC).
Note this patch series may need rebase after Simon's Minnowmax support patch series is applied.
You can rebase on x86/minnow-working if you like.
I will rebase this on u-boot-x86/master since I noticed that you have already applied the minnowmax patch series.
[snip]
Regards, Bin

Hi Bin,
On 28 January 2015 at 19:27, Bin Meng bmeng.cn@gmail.com wrote:
Hi Simon,
On Thu, Jan 29, 2015 at 2:05 AM, Simon Glass sjg@chromium.org wrote:
Hi Bin,
On 28 January 2015 at 07:19, Bin Meng bmeng.cn@gmail.com wrote:
This series adds the first step of bare support for the Intel Quark SoC support which can be validated on Intel Galileo board.
Intel Quark is a line of 32-bit x86 SoCs by Intel, designed for small size and low power consumption, and targeted at new markets including wearable devices. They are smaller and slower than Atom processors and consume less power. They lack support for SIMD instruction sets (such as MMX and SSE) and only support embedded operating systems. Quark powers the Intel Galileo developer microcontroller board. The CPU instruction set is the same as Pentium (P54C/i586) CPU.
Intel decided to completely publish Quark's hardware specification to software developers, which includes an SoC datasheet, a UEFI Firmware Writer's Guide, and a complete reference source code for the UEFI BIOS which is pre-flahsed on the Galileo board. As of today, the only BIOS for Galileo is the Intel one with UEFI inteface only. There is no CSM support yet in that BIOS, neither any 3rd party BIOS vendor provides support to Quark SoC.
So no binary blobs?
Ah, forget to mention, only one binary blob (exactly 8KiB) is needed which is rmu.bin for Remote Management Unit. Not like FSP, U-Boot will not call into the binary. The binary is needed by the Quark SoC itself. Everything on Quark will have its source codes including MRC.
Someone should suggest using on-chip ROM :-)
Note there are two generation of Galileo boards, aka gen1 and gen2. Currently the development work is on gen2, but once we get it boot, we can easily add the gen1 board (old version).
With this patch series, the generated u-boot.rom could boot the Intel Galileo board up to fdt relocate, where U-Boot hangs because the DRAM is not initializaed yet. A follow up patch series will be sent soon to add support for Memory Reference Code (MRC).
Note this patch series may need rebase after Simon's Minnowmax support patch series is applied.
You can rebase on x86/minnow-working if you like.
I will rebase this on u-boot-x86/master since I noticed that you have already applied the minnowmax patch series.
Yes it is there. Please let me know if you see any problems.
Regards, Simon
participants (2)
-
Bin Meng
-
Simon Glass