[PATCH 00/32] x86: Allow Coral to boot into Chrome OS

classic Classic list List threaded Threaded
68 messages Options
1234
Reply | Threaded
Open this post in threaded view
|

[PATCH 00/32] x86: Allow Coral to boot into Chrome OS

Simon Glass-3
This series adds various minor features and tweaks to allow Coral to boot
into Chrome OS from U-Boot.

It relies on three other series which have been recently sent:

   - smbios (u-boot-dm/smbios-working)
   - bootm (u-boot-dm/bootm-working)
   - misca (u-boot-dm/misca-working)

This should provide a solid base for using ACPI on other Intel Apollo Lake
(APL) devices.


Simon Glass (32):
  Add an assembly guard around linux/bitops.h
  x86: apl: Add core init for the SoC
  x86: Add a layout for Chrome OS verified boot
  x86: Add support for private files
  x86: Allow writing tables to fail
  x86: acpi: Store the ACPI context in global_data
  x86: Store the FADT so we can avoid searching for it
  x86: Don't bother clearing global NVS
  x86: coral: Drop the duplicate PCIe settings
  x86: Add SMBIOS info for Coral
  x86: coral: Correct max98357 file
  x86: Move ROM_TABLE_ADDR into the C file
  x86: Use if instead of #ifdef in write_tables()
  x86: Allow putting some tables in the bloblist
  x86: nhlt: Correct output of bytes and 16-bit data
  x86: nhlt: Fix a few bugs in the table generation
  x86: Show the interrupt pointer with 'irqinfo'
  x86: sound: Correct error handling
  acpi: Correct reset handling in acpi_device_add_power_res()
  x86: acpi: Allow the SSDT to be empty
  x86: acpi: Put the generated code first in DSDT
  acpi: Don't reset the tables with every new generation
  x86: Define the Chrome OS GNVS region
  x86: Use CONFIG_CHROMEOS_VBOOT for verified boot
  x86: Set up Chrome OS to boot into developer mode
  x86: Boot coral into Chrome OS by default
  x86: fsp: Convert fsp_dram to use log_debug()
  x86: Silence some logging statements
  x86: acpi: Include the TPMv1 table only if needed
  x86: acpi: Don't show the UART address by default
  x86: pinctrl: Silence the warning when a pin is not found
  x86: fsp: Adjust calculations for MTRR range and DRAM top

 Kconfig                                       |   8 ++
 arch/x86/cpu/apollolake/acpi.c                |  25 ++++-
 arch/x86/cpu/apollolake/cpu.c                 |  84 ++++++++++++++++
 arch/x86/cpu/apollolake/cpu_common.c          |  25 +++++
 arch/x86/cpu/apollolake/cpu_spl.c             |  20 ----
 arch/x86/cpu/apollolake/fsp_s.c               |   8 +-
 arch/x86/cpu/cpu.c                            |  13 ++-
 arch/x86/cpu/i386/interrupt.c                 |  14 +--
 arch/x86/cpu/intel_common/acpi.c              |   1 -
 arch/x86/cpu/intel_common/cpu.c               |  19 ++++
 arch/x86/cpu/intel_common/intel_opregion.c    |   2 +-
 arch/x86/cpu/intel_common/itss.c              |   8 +-
 arch/x86/dts/chromebook_coral.dts             |  12 ++-
 arch/x86/dts/chromebook_samus.dts             |   2 +-
 arch/x86/dts/u-boot.dtsi                      |   4 +
 arch/x86/include/asm/acpi.h                   |   9 --
 arch/x86/include/asm/acpi/vbnv_layout.h       |  38 +++++++
 arch/x86/include/asm/arch-apollolake/cpu.h    |   7 ++
 arch/x86/include/asm/cpu_common.h             |   2 +
 arch/x86/include/asm/intel_gnvs.h             |  52 +++++++++-
 arch/x86/include/asm/interrupt.h              |  17 ++++
 arch/x86/include/asm/msr-index.h              |  20 +++-
 arch/x86/include/asm/tables.h                 |  12 +--
 arch/x86/lib/acpi.c                           |  57 -----------
 arch/x86/lib/acpi_nhlt.c                      |  19 +++-
 arch/x86/lib/acpi_table.c                     |  79 ++++++++++-----
 arch/x86/lib/fsp/fsp_dram.c                   |  35 ++++---
 arch/x86/lib/fsp/fsp_graphics.c               |   2 +-
 arch/x86/lib/fsp2/fsp_dram.c                  |   8 +-
 arch/x86/lib/interrupts.c                     |   3 +
 arch/x86/lib/tables.c                         |  93 ++++++++++++++----
 arch/x86/lib/tpl.c                            |   2 +-
 .../max98357-render-2ch-48khz-24b.dat         | Bin 0 -> 116 bytes
 configs/chromebook_coral_defconfig            |  13 ++-
 drivers/core/acpi.c                           |  10 +-
 drivers/pinctrl/intel/pinctrl.c               |   2 +-
 drivers/sound/da7219.c                        |   4 +-
 drivers/sound/max98357a.c                     |   2 +-
 include/acpi/acpi_table.h                     |  10 ++
 include/asm-generic/global_data.h             |   5 +
 include/configs/chromebook_coral.h            |   9 +-
 include/dm/acpi.h                             |  11 +++
 include/linux/bitops.h                        |   4 +-
 lib/Kconfig                                   |   9 ++
 lib/acpi/acpi_device.c                        |   2 +-
 lib/acpi/acpi_table.c                         |   4 +-
 test/dm/acpi.c                                |   4 +
 47 files changed, 573 insertions(+), 216 deletions(-)
 create mode 100644 arch/x86/include/asm/acpi/vbnv_layout.h

--
2.28.0.681.g6f77f65b4e-goog

Reply | Threaded
Open this post in threaded view
|

[PATCH 01/32] Add an assembly guard around linux/bitops.h

Simon Glass-3
This file can be included by any header but it includes C code. Guard it
to avoid errors when compiling ASL, etc.

Signed-off-by: Simon Glass <[hidden email]>
---

 include/linux/bitops.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/linux/bitops.h b/include/linux/bitops.h
index 6b509dce58a..16f28993f5e 100644
--- a/include/linux/bitops.h
+++ b/include/linux/bitops.h
@@ -1,7 +1,7 @@
 #ifndef _LINUX_BITOPS_H
 #define _LINUX_BITOPS_H
 
-#ifndef USE_HOSTCC
+#if !defined(USE_HOSTCC) && !defined(__ASSEMBLY__)
 
 #include <asm/types.h>
 #include <asm-generic/bitsperlong.h>
@@ -218,6 +218,6 @@ static inline void generic_clear_bit(int nr, volatile unsigned long *addr)
  *p &= ~mask;
 }
 
-#endif /* !USE_HOSTCC */
+#endif /* !USE_HOSTCC && !__ASSEMBLY__ */
 
 #endif
--
2.28.0.681.g6f77f65b4e-goog

Reply | Threaded
Open this post in threaded view
|

[PATCH 02/32] x86: apl: Add core init for the SoC

Simon Glass-3
In reply to this post by Simon Glass-3
Set up MSRs required for Apollo Lake. This enables Linux to use the
timers correctly. Also write the fixed MSRs for this platform.

Signed-off-by: Simon Glass <[hidden email]>
---

 arch/x86/cpu/apollolake/cpu.c              | 84 ++++++++++++++++++++++
 arch/x86/cpu/apollolake/cpu_common.c       | 25 +++++++
 arch/x86/cpu/apollolake/cpu_spl.c          | 20 ------
 arch/x86/cpu/intel_common/cpu.c            | 19 +++++
 arch/x86/include/asm/arch-apollolake/cpu.h |  7 ++
 arch/x86/include/asm/cpu_common.h          |  2 +
 arch/x86/include/asm/msr-index.h           | 20 +++++-
 7 files changed, 156 insertions(+), 21 deletions(-)

diff --git a/arch/x86/cpu/apollolake/cpu.c b/arch/x86/cpu/apollolake/cpu.c
index 8da2e64e226..e39b4cfba3c 100644
--- a/arch/x86/cpu/apollolake/cpu.c
+++ b/arch/x86/cpu/apollolake/cpu.c
@@ -13,6 +13,9 @@
 #include <asm/cpu_x86.h>
 #include <asm/intel_acpi.h>
 #include <asm/msr.h>
+#include <asm/mtrr.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/iomap.h>
 #include <dm/acpi.h>
 
 #define CSTATE_RES(address_space, width, offset, address) \
@@ -86,6 +89,86 @@ static int acpi_cpu_fill_ssdt(const struct udevice *dev, struct acpi_ctx *ctx)
  return 0;
 }
 
+static void update_fixed_mtrss(void)
+{
+ native_write_msr(MTRR_FIX_64K_00000_MSR,
+ MTRR_FIX_TYPE(MTRR_TYPE_WRBACK),
+ MTRR_FIX_TYPE(MTRR_TYPE_WRBACK));
+ native_write_msr(MTRR_FIX_16K_80000_MSR,
+ MTRR_FIX_TYPE(MTRR_TYPE_WRBACK),
+ MTRR_FIX_TYPE(MTRR_TYPE_WRBACK));
+ native_write_msr(MTRR_FIX_4K_E0000_MSR,
+ MTRR_FIX_TYPE(MTRR_TYPE_WRBACK),
+ MTRR_FIX_TYPE(MTRR_TYPE_WRBACK));
+ native_write_msr(MTRR_FIX_4K_E8000_MSR,
+ MTRR_FIX_TYPE(MTRR_TYPE_WRBACK),
+ MTRR_FIX_TYPE(MTRR_TYPE_WRBACK));
+ native_write_msr(MTRR_FIX_4K_F0000_MSR,
+ MTRR_FIX_TYPE(MTRR_TYPE_WRBACK),
+ MTRR_FIX_TYPE(MTRR_TYPE_WRBACK));
+ native_write_msr(MTRR_FIX_4K_F8000_MSR,
+ MTRR_FIX_TYPE(MTRR_TYPE_WRBACK),
+ MTRR_FIX_TYPE(MTRR_TYPE_WRBACK));
+}
+
+static void setup_core_msrs(void)
+{
+ wrmsrl(MSR_PMG_CST_CONFIG_CONTROL,
+       PKG_C_STATE_LIMIT_C2_MASK | CORE_C_STATE_LIMIT_C10_MASK |
+       IO_MWAIT_REDIRECT_MASK | CST_CFG_LOCK_MASK);
+ /* Power Management I/O base address for I/O trapping to C-states */
+ wrmsrl(MSR_PMG_IO_CAPTURE_ADR, ACPI_PMIO_CST_REG |
+       (PMG_IO_BASE_CST_RNG_BLK_SIZE << 16));
+ /* Disable C1E */
+ msr_clrsetbits_64(MSR_POWER_CTL, 0x2, 0);
+ /* Disable support for MONITOR and MWAIT instructions */
+ msr_clrsetbits_64(MSR_IA32_MISC_ENABLE, MISC_ENABLE_MWAIT, 0);
+ /*
+ * Enable and Lock the Advanced Encryption Standard (AES-NI)
+ * feature register
+ */
+ msr_clrsetbits_64(MSR_FEATURE_CONFIG, FEATURE_CONFIG_RESERVED_MASK,
+  FEATURE_CONFIG_LOCK);
+
+ update_fixed_mtrss();
+}
+
+static int soc_core_init(void)
+{
+ struct udevice *pmc;
+ int ret;
+
+ /* Clear out pending MCEs */
+ cpu_mca_configure();
+
+ /* Set core MSRs */
+ setup_core_msrs();
+ /*
+ * Enable ACPI PM timer emulation, which also lets microcode know
+ * location of ACPI_BASE_ADDRESS. This also enables other features
+ * implemented in microcode.
+ */
+ ret = uclass_first_device_err(UCLASS_ACPI_PMC, &pmc);
+ if (ret)
+ return log_msg_ret("PMC", ret);
+ enable_pm_timer_emulation(pmc);
+
+ return 0;
+}
+
+static int cpu_apl_probe(struct udevice *dev)
+{
+ if (gd->flags & GD_FLG_RELOC) {
+ int ret;
+
+ ret = soc_core_init();
+ if (ret)
+ return log_ret(ret);
+ }
+
+ return 0;
+}
+
 struct acpi_ops apl_cpu_acpi_ops = {
  .fill_ssdt = acpi_cpu_fill_ssdt,
 };
@@ -107,6 +190,7 @@ U_BOOT_DRIVER(cpu_x86_apl_drv) = {
  .id = UCLASS_CPU,
  .of_match = cpu_x86_apl_ids,
  .bind = cpu_x86_bind,
+ .probe = cpu_apl_probe,
  .ops = &cpu_x86_apl_ops,
  ACPI_OPS_PTR(&apl_cpu_acpi_ops)
  .flags = DM_FLAG_PRE_RELOC,
diff --git a/arch/x86/cpu/apollolake/cpu_common.c b/arch/x86/cpu/apollolake/cpu_common.c
index ba6bda37bc5..63f6999b024 100644
--- a/arch/x86/cpu/apollolake/cpu_common.c
+++ b/arch/x86/cpu/apollolake/cpu_common.c
@@ -4,8 +4,13 @@
  */
 
 #include <common.h>
+#include <dm.h>
+#include <log.h>
 #include <asm/cpu_common.h>
 #include <asm/msr.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/iomap.h>
+#include <power/acpi_pmc.h>
 
 void cpu_flush_l1d_to_l2(void)
 {
@@ -15,3 +20,23 @@ void cpu_flush_l1d_to_l2(void)
  msr.lo |= FLUSH_DL1_L2;
  msr_write(MSR_POWER_MISC, msr);
 }
+
+void enable_pm_timer_emulation(const struct udevice *pmc)
+{
+ struct acpi_pmc_upriv *upriv = dev_get_uclass_priv(pmc);
+ msr_t msr;
+
+ /*
+ * The derived frequency is calculated as follows:
+ *    (CTC_FREQ * msr[63:32]) >> 32 = target frequency.
+ *
+ * Back-solve the multiplier so the 3.579545MHz ACPI timer frequency is
+ * used.
+ */
+ msr.hi = (3579545ULL << 32) / CTC_FREQ;
+
+ /* Set PM1 timer IO port and enable */
+ msr.lo = EMULATE_PM_TMR_EN | (upriv->acpi_base + R_ACPI_PM1_TMR);
+ debug("PM timer %x %x\n", msr.hi, msr.lo);
+ msr_write(MSR_EMULATE_PM_TIMER, msr);
+}
diff --git a/arch/x86/cpu/apollolake/cpu_spl.c b/arch/x86/cpu/apollolake/cpu_spl.c
index 9f32f2e27e1..fafe4dbc0a0 100644
--- a/arch/x86/cpu/apollolake/cpu_spl.c
+++ b/arch/x86/cpu/apollolake/cpu_spl.c
@@ -114,26 +114,6 @@ static int fast_spi_cache_bios_region(void)
  return 0;
 }
 
-static void enable_pm_timer_emulation(struct udevice *pmc)
-{
- struct acpi_pmc_upriv *upriv = dev_get_uclass_priv(pmc);
- msr_t msr;
-
- /*
- * The derived frequency is calculated as follows:
- *    (CTC_FREQ * msr[63:32]) >> 32 = target frequency.
- *
- * Back-solve the multiplier so the 3.579545MHz ACPI timer frequency is
- * used.
- */
- msr.hi = (3579545ULL << 32) / CTC_FREQ;
-
- /* Set PM1 timer IO port and enable */
- msr.lo = EMULATE_PM_TMR_EN | (upriv->acpi_base + R_ACPI_PM1_TMR);
- debug("PM timer %x %x\n", msr.hi, msr.lo);
- msr_write(MSR_EMULATE_PM_TIMER, msr);
-}
-
 static void google_chromeec_ioport_range(uint *out_basep, uint *out_sizep)
 {
  uint base;
diff --git a/arch/x86/cpu/intel_common/cpu.c b/arch/x86/cpu/intel_common/cpu.c
index 39aa0f63c65..c756fe08906 100644
--- a/arch/x86/cpu/intel_common/cpu.c
+++ b/arch/x86/cpu/intel_common/cpu.c
@@ -306,3 +306,22 @@ int cpu_get_cores_per_package(void)
 
  return cores;
 }
+
+void cpu_mca_configure(void)
+{
+ msr_t msr;
+ int i;
+ int num_banks;
+
+ msr = msr_read(MSR_IA32_MCG_CAP);
+ num_banks = msr.lo & 0xff;
+ msr.lo = 0;
+ msr.hi = 0;
+ for (i = 0; i < num_banks; i++) {
+ /* Clear the machine check status */
+ msr_write(MSR_IA32_MC0_STATUS + (i * 4), msr);
+ /* Initialize machine checks */
+ msr_write(MSR_IA32_MC0_CTL + i * 4,
+  (msr_t) {.lo = 0xffffffff, .hi = 0xffffffff});
+ }
+}
diff --git a/arch/x86/include/asm/arch-apollolake/cpu.h b/arch/x86/include/asm/arch-apollolake/cpu.h
index 5e906c5e7d7..a692104cd1f 100644
--- a/arch/x86/include/asm/arch-apollolake/cpu.h
+++ b/arch/x86/include/asm/arch-apollolake/cpu.h
@@ -15,6 +15,13 @@
 #ifndef __ASSEMBLY__
 /* Flush L1D to L2 */
 void cpu_flush_l1d_to_l2(void);
+
+/**
+ * Enable emulation of the PM timer
+ *
+ * @pmc: PMC device
+ */
+void enable_pm_timer_emulation(const struct udevice *pmc);
 #endif
 
 #endif /* _ASM_ARCH_CPU_H */
diff --git a/arch/x86/include/asm/cpu_common.h b/arch/x86/include/asm/cpu_common.h
index 48f56c2aad9..66311de7fdc 100644
--- a/arch/x86/include/asm/cpu_common.h
+++ b/arch/x86/include/asm/cpu_common.h
@@ -184,4 +184,6 @@ int cpu_get_max_turbo_ratio(void);
  */
 int cpu_get_cores_per_package(void);
 
+void cpu_mca_configure(void);
+
 #endif
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index 94e6b18e21c..c49b4225ac2 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -68,7 +68,18 @@
 #define MSR_BSEL_CR_OVERCLOCK_CONTROL 0x000000cd
 #define MSR_PLATFORM_INFO 0x000000ce
 #define MSR_PMG_CST_CONFIG_CONTROL 0x000000e2
-#define SINGLE_PCTL (1 << 11)
+/* Set MSR_PMG_CST_CONFIG_CONTROL[3:0] for Package C-State limit */
+#define   PKG_C_STATE_LIMIT_C2_MASK BIT(1)
+/* Set MSR_PMG_CST_CONFIG_CONTROL[7:4] for Core C-State limit*/
+#define   CORE_C_STATE_LIMIT_C10_MASK 0x70
+/* Set MSR_PMG_CST_CONFIG_CONTROL[10] to IO redirect to MWAIT */
+#define   IO_MWAIT_REDIRECT_MASK BIT(10)
+/* Set MSR_PMG_CST_CONFIG_CONTROL[15] to lock CST_CFG [0-15] bits */
+#define   CST_CFG_LOCK_MASK BIT(15)
+#define   SINGLE_PCTL BIT(11)
+
+/* ACPI PMIO Offset to C-state register */
+#define ACPI_PMIO_CST_REG (ACPI_BASE_ADDRESS + 0x14)
 
 #define MSR_MTRRcap 0x000000fe
 #define MSR_IA32_BBL_CR_CTL 0x00000119
@@ -83,6 +94,10 @@
 #define  EMULATE_PM_TMR_EN (1 << 16)
 #define  EMULATE_DELAY_VALUE 0x13
 
+#define MSR_FEATURE_CONFIG 0x13c
+#define   FEATURE_CONFIG_RESERVED_MASK 0x3ULL
+#define   FEATURE_CONFIG_LOCK (1 << 0)
+
 #define MSR_IA32_SYSENTER_CS 0x00000174
 #define MSR_IA32_SYSENTER_ESP 0x00000175
 #define MSR_IA32_SYSENTER_EIP 0x00000176
@@ -453,6 +468,9 @@
 #define MSR_AMD_PERF_CTL 0xc0010062
 
 #define MSR_PMG_CST_CONFIG_CTL 0x000000e2
+/* CST Range (R/W) IO port block size */
+#define PMG_IO_BASE_CST_RNG_BLK_SIZE 0x5
+
 #define MSR_PMG_IO_CAPTURE_ADR 0x000000e4
 #define MSR_IA32_MPERF 0x000000e7
 #define MSR_IA32_APERF 0x000000e8
--
2.28.0.681.g6f77f65b4e-goog

Reply | Threaded
Open this post in threaded view
|

[PATCH 03/32] x86: Add a layout for Chrome OS verified boot

Simon Glass-3
In reply to this post by Simon Glass-3
Add definitions for part of the vboot context used with verified boot.

Signed-off-by: Simon Glass <[hidden email]>
---

 arch/x86/include/asm/acpi/vbnv_layout.h | 38 +++++++++++++++++++++++++
 1 file changed, 38 insertions(+)
 create mode 100644 arch/x86/include/asm/acpi/vbnv_layout.h

diff --git a/arch/x86/include/asm/acpi/vbnv_layout.h b/arch/x86/include/asm/acpi/vbnv_layout.h
new file mode 100644
index 00000000000..8bc4e9534ef
--- /dev/null
+++ b/arch/x86/include/asm/acpi/vbnv_layout.h
@@ -0,0 +1,38 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020 Google LLC
+ */
+
+#ifndef __ASM_ACPI_VBNV_LAYOUT_H__
+#define __ASM_ACPI_VBNV_LAYOUT_H__
+
+#define VBOOT_VBNV_BLOCK_SIZE 16 /* Size of NV storage block in bytes */
+
+/* Constants for NV storage, for use with ACPI */
+#define HEADER_OFFSET 0
+#define HEADER_MASK 0xc0
+#define HEADER_SIGNATURE 0x40
+#define HEADER_FIRMWARE_SETTINGS_RESET  0x20
+#define HEADER_KERNEL_SETTINGS_RESET    0x10
+
+#define BOOT_OFFSET 1
+#define BOOT_DEBUG_RESET_MODE 0x80
+#define BOOT_DISABLE_DEV_REQUEST 0x40
+#define BOOT_DISPLAY_REQUEST 0x20
+#define BOOT_TRY_B_COUNT_MASK 0x0f
+
+#define RECOVERY_OFFSET 2
+#define LOCALIZATION_OFFSET 3
+
+#define DEV_FLAGS_OFFSET 4
+#define DEV_BOOT_USB_MASK 0x01
+#define DEV_BOOT_SIGNED_ONLY_MASK 0x02
+#define DEV_ENABLE_UDC 0x40
+
+#define MISC_FLAGS_OFFSET 8
+#define MISC_FLAGS_BATTERY_CUTOFF_MASK 0x08
+
+#define KERNEL_FIELD_OFFSET 11
+#define CRC_OFFSET 15
+
+#endif /* __ASM_ACPI_VBNV_LAYOUT_H__ */
--
2.28.0.681.g6f77f65b4e-goog

Reply | Threaded
Open this post in threaded view
|

[PATCH 04/32] x86: Add support for private files

Simon Glass-3
In reply to this post by Simon Glass-3
Some boards need to include binary data into the image for use during the
boot process. Add a node for these.

An example is the audio-codec configuration used by some audio drivers on
Intel platforms. If no private files are provided, they will be omitted.

Signed-off-by: Simon Glass <[hidden email]>
---

 arch/x86/dts/u-boot.dtsi | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/x86/dts/u-boot.dtsi b/arch/x86/dts/u-boot.dtsi
index 0afdcac28d9..754df3d8749 100644
--- a/arch/x86/dts/u-boot.dtsi
+++ b/arch/x86/dts/u-boot.dtsi
@@ -138,6 +138,10 @@
  filename = CONFIG_FSP_FILE_S;
  };
 #endif
+ private_files: private-files {
+ type = "files";
+ pattern = "*.dat";
+ };
 #if IS_ENABLED(CONFIG_HAVE_MRC) || IS_ENABLED(CONFIG_FSP_VERSION2)
  rw-mrc-cache {
  type = "blob";
--
2.28.0.681.g6f77f65b4e-goog

Reply | Threaded
Open this post in threaded view
|

[PATCH 05/32] x86: Allow writing tables to fail

Simon Glass-3
In reply to this post by Simon Glass-3
At present write_tables() can fail but does not report this problem to its
caller. Fix this by changing the return type.

Signed-off-by: Simon Glass <[hidden email]>
---

 arch/x86/cpu/cpu.c            | 7 ++++++-
 arch/x86/include/asm/tables.h | 4 +++-
 arch/x86/lib/tables.c         | 5 ++++-
 3 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/arch/x86/cpu/cpu.c b/arch/x86/cpu/cpu.c
index f8692753963..5c33f02f034 100644
--- a/arch/x86/cpu/cpu.c
+++ b/arch/x86/cpu/cpu.c
@@ -200,6 +200,7 @@ __weak void board_final_cleanup(void)
 int last_stage_init(void)
 {
  struct acpi_fadt __maybe_unused *fadt;
+ int ret;
 
  board_final_init();
 
@@ -210,7 +211,11 @@ int last_stage_init(void)
  acpi_resume(fadt);
  }
 
- write_tables();
+ ret = write_tables();
+ if (ret) {
+ printf("Failed to write tables\n");
+ return log_msg_ret("table", ret);
+ }
 
  if (IS_ENABLED(CONFIG_GENERATE_ACPI_TABLE)) {
  fadt = acpi_find_fadt();
diff --git a/arch/x86/include/asm/tables.h b/arch/x86/include/asm/tables.h
index f7c72ed3db0..bf66e79018e 100644
--- a/arch/x86/include/asm/tables.h
+++ b/arch/x86/include/asm/tables.h
@@ -49,8 +49,10 @@ void table_fill_string(char *dest, const char *src, size_t n, char pad);
  * This writes x86 configuration tables, including PIRQ routing table,
  * Multi-Processor table and ACPI table. Whether a specific type of
  * configuration table is written is controlled by a Kconfig option.
+ *
+ * @return 0 if OK, -ENOSPC if table too large
  */
-void write_tables(void);
+int write_tables(void);
 
 /**
  * write_pirq_routing_table() - Write PIRQ routing table
diff --git a/arch/x86/lib/tables.c b/arch/x86/lib/tables.c
index 7bad5dd3032..7099866a78a 100644
--- a/arch/x86/lib/tables.c
+++ b/arch/x86/lib/tables.c
@@ -64,7 +64,7 @@ void table_fill_string(char *dest, const char *src, size_t n, char pad)
  dest[i] = pad;
 }
 
-void write_tables(void)
+int write_tables(void)
 {
  u32 rom_table_start = ROM_TABLE_ADDR;
  u32 rom_table_end;
@@ -91,6 +91,7 @@ void write_tables(void)
  cfg_tables[i].size = table_size;
  } else {
  printf("%d: no memory for configuration tables\n", i);
+ return -ENOSPC;
  }
 #endif
 
@@ -105,4 +106,6 @@ void write_tables(void)
  write_coreboot_table(CB_TABLE_ADDR, cfg_tables);
 #endif
  debug("- done writing tables\n");
+
+ return 0;
 }
--
2.28.0.681.g6f77f65b4e-goog

Reply | Threaded
Open this post in threaded view
|

[PATCH 06/32] x86: acpi: Store the ACPI context in global_data

Simon Glass-3
In reply to this post by Simon Glass-3
At present we create the ACPI context but then drop it after generation of
tables is complete. This is annoying because we have to then search for
tables later.

To fix this, allocate the context and store it in global_data.

Signed-off-by: Simon Glass <[hidden email]>
---

 arch/x86/lib/acpi_table.c         | 7 ++++++-
 include/asm-generic/global_data.h | 5 +++++
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/arch/x86/lib/acpi_table.c b/arch/x86/lib/acpi_table.c
index 6d405b09fde..f0f342d8935 100644
--- a/arch/x86/lib/acpi_table.c
+++ b/arch/x86/lib/acpi_table.c
@@ -494,7 +494,7 @@ void acpi_create_ssdt(struct acpi_ctx *ctx, struct acpi_table_header *ssdt,
  */
 ulong write_acpi_tables(ulong start_addr)
 {
- struct acpi_ctx sctx, *ctx = &sctx;
+ struct acpi_ctx *ctx;
  struct acpi_facs *facs;
  struct acpi_table_header *dsdt;
  struct acpi_fadt *fadt;
@@ -509,6 +509,11 @@ ulong write_acpi_tables(ulong start_addr)
  int ret;
  int i;
 
+ ctx = calloc(1, sizeof(*ctx));
+ if (!ctx)
+ return log_msg_ret("mem", -ENOMEM);
+ gd->acpi_ctx = ctx;
+
  start = map_sysmem(start_addr, 0);
 
  debug("ACPI: Writing ACPI tables at %lx\n", start_addr);
diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h
index d4a4e2215dc..c10033a8692 100644
--- a/include/asm-generic/global_data.h
+++ b/include/asm-generic/global_data.h
@@ -24,6 +24,8 @@
 #include <membuff.h>
 #include <linux/list.h>
 
+struct acpi_ctx;
+
 typedef struct global_data {
  struct bd_info *bd;
  unsigned long flags;
@@ -137,6 +139,9 @@ typedef struct global_data {
 #if CONFIG_IS_ENABLED(WDT)
  struct udevice *watchdog_dev;
 #endif
+#ifdef CONFIG_GENERATE_ACPI_TABLE
+ struct acpi_ctx *acpi_ctx;
+#endif
 } gd_t;
 #endif
 
--
2.28.0.681.g6f77f65b4e-goog

Reply | Threaded
Open this post in threaded view
|

[PATCH 07/32] x86: Store the FADT so we can avoid searching for it

Simon Glass-3
In reply to this post by Simon Glass-3
Put the FADT in global_data and access it as needed. Drop the functions
which search for it.

Signed-off-by: Simon Glass <[hidden email]>
---

 arch/x86/cpu/cpu.c          |  6 ++--
 arch/x86/include/asm/acpi.h |  9 ------
 arch/x86/lib/acpi.c         | 57 -------------------------------------
 arch/x86/lib/acpi_table.c   |  1 +
 include/dm/acpi.h           |  2 ++
 5 files changed, 6 insertions(+), 69 deletions(-)

diff --git a/arch/x86/cpu/cpu.c b/arch/x86/cpu/cpu.c
index 5c33f02f034..6cbfc0c8488 100644
--- a/arch/x86/cpu/cpu.c
+++ b/arch/x86/cpu/cpu.c
@@ -199,13 +199,13 @@ __weak void board_final_cleanup(void)
 
 int last_stage_init(void)
 {
- struct acpi_fadt __maybe_unused *fadt;
+ struct acpi_fadt *fadt;
  int ret;
 
  board_final_init();
 
  if (IS_ENABLED(CONFIG_HAVE_ACPI_RESUME)) {
- fadt = acpi_find_fadt();
+ fadt = gd->acpi_ctx->fadt;
 
  if (fadt && gd->arch.prev_sleep_state == ACPI_S3)
  acpi_resume(fadt);
@@ -218,7 +218,7 @@ int last_stage_init(void)
  }
 
  if (IS_ENABLED(CONFIG_GENERATE_ACPI_TABLE)) {
- fadt = acpi_find_fadt();
+ fadt = gd->acpi_ctx->fadt;
 
  /* Don't touch ACPI hardware on HW reduced platforms */
  if (fadt && !(fadt->flags & ACPI_FADT_HW_REDUCED_ACPI)) {
diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h
index 4475d046e8c..2023e2b0460 100644
--- a/arch/x86/include/asm/acpi.h
+++ b/arch/x86/include/asm/acpi.h
@@ -8,15 +8,6 @@
 
 struct acpi_fadt;
 
-/**
- * acpi_find_fadt() - find ACPI FADT table in the system memory
- *
- * This routine parses the ACPI table to locate the ACPI FADT table.
- *
- * @return: a pointer to the ACPI FADT table in the system memory
- */
-struct acpi_fadt *acpi_find_fadt(void);
-
 /**
  * acpi_find_wakeup_vector() - find OS installed wake up vector address
  *
diff --git a/arch/x86/lib/acpi.c b/arch/x86/lib/acpi.c
index 155fffabf08..20f1bb79b35 100644
--- a/arch/x86/lib/acpi.c
+++ b/arch/x86/lib/acpi.c
@@ -9,63 +9,6 @@
 #include <asm/io.h>
 #include <asm/tables.h>
 
-static struct acpi_rsdp *acpi_valid_rsdp(struct acpi_rsdp *rsdp)
-{
- if (strncmp((char *)rsdp, RSDP_SIG, sizeof(RSDP_SIG) - 1) != 0)
- return NULL;
-
- debug("Looking on %p for valid checksum\n", rsdp);
-
- if (table_compute_checksum((void *)rsdp, 20) != 0)
- return NULL;
- debug("acpi rsdp checksum 1 passed\n");
-
- if ((rsdp->revision > 1) &&
-    (table_compute_checksum((void *)rsdp, rsdp->length) != 0))
- return NULL;
- debug("acpi rsdp checksum 2 passed\n");
-
- return rsdp;
-}
-
-struct acpi_fadt *acpi_find_fadt(void)
-{
- char *p, *end;
- struct acpi_rsdp *rsdp = NULL;
- struct acpi_rsdt *rsdt;
- struct acpi_fadt *fadt = NULL;
- int i;
-
- /* Find RSDP */
- for (p = (char *)ROM_TABLE_ADDR; p < (char *)ROM_TABLE_END; p += 16) {
- rsdp = acpi_valid_rsdp((struct acpi_rsdp *)p);
- if (rsdp)
- break;
- }
-
- if (!rsdp)
- return NULL;
-
- debug("RSDP found at %p\n", rsdp);
- rsdt = (struct acpi_rsdt *)(uintptr_t)rsdp->rsdt_address;
-
- end = (char *)rsdt + rsdt->header.length;
- debug("RSDT found at %p ends at %p\n", rsdt, end);
-
- for (i = 0; ((char *)&rsdt->entry[i]) < end; i++) {
- fadt = (struct acpi_fadt *)(uintptr_t)rsdt->entry[i];
- if (strncmp((char *)fadt, "FACP", 4) == 0)
- break;
- fadt = NULL;
- }
-
- if (!fadt)
- return NULL;
-
- debug("FADT found at %p\n", fadt);
- return fadt;
-}
-
 void *acpi_find_wakeup_vector(struct acpi_fadt *fadt)
 {
  struct acpi_facs *facs;
diff --git a/arch/x86/lib/acpi_table.c b/arch/x86/lib/acpi_table.c
index f0f342d8935..e0130ad5230 100644
--- a/arch/x86/lib/acpi_table.c
+++ b/arch/x86/lib/acpi_table.c
@@ -590,6 +590,7 @@ ulong write_acpi_tables(ulong start_addr)
 
  debug("ACPI:    * FADT\n");
  fadt = ctx->current;
+ ctx->fadt = fadt;
  acpi_inc_align(ctx, sizeof(struct acpi_fadt));
  acpi_create_fadt(fadt, facs, dsdt);
  acpi_add_table(ctx, fadt);
diff --git a/include/dm/acpi.h b/include/dm/acpi.h
index e8b0336f6d8..a200305e640 100644
--- a/include/dm/acpi.h
+++ b/include/dm/acpi.h
@@ -46,6 +46,7 @@ enum acpi_dump_option {
  * adding a new table. The RSDP holds pointers to the RSDT and XSDT.
  * @rsdt: Pointer to the Root System Description Table
  * @xsdt: Pointer to the Extended System Description Table
+ * @fadt: Pointer to the Fixed ACPI Description Table
  * @nhlt: Intel Non-High-Definition-Audio Link Table (NHLT) pointer, used to
  * build up information that audio codecs need to provide in the NHLT ACPI
  * table
@@ -58,6 +59,7 @@ struct acpi_ctx {
  struct acpi_rsdp *rsdp;
  struct acpi_rsdt *rsdt;
  struct acpi_xsdt *xsdt;
+ struct acpi_fadt *fadt;
  struct nhlt *nhlt;
  char *len_stack[ACPIGEN_LENSTACK_SIZE];
  int ltop;
--
2.28.0.681.g6f77f65b4e-goog

Reply | Threaded
Open this post in threaded view
|

[PATCH 08/32] x86: Don't bother clearing global NVS

Simon Glass-3
In reply to this post by Simon Glass-3
The bloblist guarantees that blobs are zeroed so there is no need to do
an additional memset(). Drop it.

Signed-off-by: Simon Glass <[hidden email]>
---

 arch/x86/cpu/intel_common/acpi.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/x86/cpu/intel_common/acpi.c b/arch/x86/cpu/intel_common/acpi.c
index 42f87165f0c..9b183d66ae9 100644
--- a/arch/x86/cpu/intel_common/acpi.c
+++ b/arch/x86/cpu/intel_common/acpi.c
@@ -202,7 +202,6 @@ int southbridge_inject_dsdt(const struct udevice *dev, struct acpi_ctx *ctx)
    (void **)&gnvs);
  if (ret)
  return log_msg_ret("bloblist", ret);
- memset(gnvs, '\0', sizeof(*gnvs));
 
  ret = acpi_create_gnvs(gnvs);
  if (ret)
--
2.28.0.681.g6f77f65b4e-goog

Reply | Threaded
Open this post in threaded view
|

[PATCH 09/32] x86: coral: Drop the duplicate PCIe settings

Simon Glass-3
In reply to this post by Simon Glass-3
These settings are included twice. The second lot are correct, so drop the
others.

Signed-off-by: Simon Glass <[hidden email]>
Reported-by: Wolfgang Wallner <[hidden email]>
---

 arch/x86/dts/chromebook_coral.dts | 2 --
 1 file changed, 2 deletions(-)

diff --git a/arch/x86/dts/chromebook_coral.dts b/arch/x86/dts/chromebook_coral.dts
index 893a59b1620..8801b58bb54 100644
--- a/arch/x86/dts/chromebook_coral.dts
+++ b/arch/x86/dts/chromebook_coral.dts
@@ -718,8 +718,6 @@
 
  fsps,ish-enable = <0>;
  fsps,enable-sata = <0>;
- fsps,pcie-root-port-en = [00 00 00 00 00 01];
- fsps,pcie-rp-hot-plug = [00 00 00 00 00 01];
  fsps,i2c6-enable = <I2CX_ENABLE_DISABLED>;
  fsps,i2c7-enable = <I2CX_ENABLE_DISABLED>;
  fsps,hsuart3-enable = <HSUARTX_ENABLE_DISABLED>;
--
2.28.0.681.g6f77f65b4e-goog

Reply | Threaded
Open this post in threaded view
|

[PATCH 10/32] x86: Add SMBIOS info for Coral

Simon Glass-3
In reply to this post by Simon Glass-3
This is required by Chrome OS so that the audio and other unibuild
features work correctly. Add it.

Signed-off-by: Simon Glass <[hidden email]>
---

 arch/x86/dts/chromebook_coral.dts | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/x86/dts/chromebook_coral.dts b/arch/x86/dts/chromebook_coral.dts
index 8801b58bb54..92f70b13dd7 100644
--- a/arch/x86/dts/chromebook_coral.dts
+++ b/arch/x86/dts/chromebook_coral.dts
@@ -54,6 +54,14 @@
  recovery-gpios = <&gpio_nw (-1) GPIO_ACTIVE_LOW>;
  write-protect-gpios = <&gpio_nw GPIO_75 GPIO_ACTIVE_HIGH>;
  phase-enforce-gpios = <&gpio_n GPIO_10 GPIO_ACTIVE_HIGH>;
+ smbios {
+ manufacturer = "Google";
+ product = "Coral";
+ version = "rev2";
+ serial = "123456789";
+ sku = "sku3";
+ family = "Google_Coral";
+ };
  };
 
  config {
--
2.28.0.681.g6f77f65b4e-goog

Reply | Threaded
Open this post in threaded view
|

[PATCH 11/32] x86: coral: Correct max98357 file

Simon Glass-3
In reply to this post by Simon Glass-3
This somehow ended up as an empty file. Fix it.

Signed-off-by: Simon Glass <[hidden email]>
---

 .../max98357-render-2ch-48khz-24b.dat             | Bin 0 -> 116 bytes
 1 file changed, 0 insertions(+), 0 deletions(-)

diff --git a/board/google/chromebook_coral/max98357-render-2ch-48khz-24b.dat b/board/google/chromebook_coral/max98357-render-2ch-48khz-24b.dat
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..b0b5b9ba648c4546f98e15e42356a5fc4af6bb27 100644
GIT binary patch
literal 116
zcmZQzU|?WnWOx?=qy_%}|BnyXGahJUU??~MR0;$VT+Bccgqa+G1PJi6vnv28CMf>T
R&%gk}Aix2{5<r{+!~hE!AMpSH

literal 0
HcmV?d00001

--
2.28.0.681.g6f77f65b4e-goog

Reply | Threaded
Open this post in threaded view
|

[PATCH 12/32] x86: Move ROM_TABLE_ADDR into the C file

Simon Glass-3
In reply to this post by Simon Glass-3
At present this is defined in the header file, along with a few related
defines. The code that used to need this has been removed. Move it into
the C file instead.

Signed-off-by: Simon Glass <[hidden email]>
---

 arch/x86/include/asm/tables.h | 8 --------
 arch/x86/lib/tables.c         | 8 ++++++++
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/arch/x86/include/asm/tables.h b/arch/x86/include/asm/tables.h
index bf66e79018e..ff15949bd47 100644
--- a/arch/x86/include/asm/tables.h
+++ b/arch/x86/include/asm/tables.h
@@ -8,14 +8,6 @@
 
 #include <tables_csum.h>
 
-#define ROM_TABLE_ADDR CONFIG_ROM_TABLE_ADDR
-#define ROM_TABLE_END (CONFIG_ROM_TABLE_ADDR + CONFIG_ROM_TABLE_SIZE - 1)
-
-#define ROM_TABLE_ALIGN 1024
-
-/* SeaBIOS expects coreboot tables at address range 0x0000-0x1000 */
-#define CB_TABLE_ADDR 0x800
-
 /**
  * table_compute_checksum() - Compute a table checksum
  *
diff --git a/arch/x86/lib/tables.c b/arch/x86/lib/tables.c
index 7099866a78a..43b61a7aeac 100644
--- a/arch/x86/lib/tables.c
+++ b/arch/x86/lib/tables.c
@@ -13,6 +13,14 @@
 #include <asm/tables.h>
 #include <asm/coreboot_tables.h>
 
+#define ROM_TABLE_ADDR CONFIG_ROM_TABLE_ADDR
+#define ROM_TABLE_END (CONFIG_ROM_TABLE_ADDR + CONFIG_ROM_TABLE_SIZE - 1)
+
+#define ROM_TABLE_ALIGN 1024
+
+/* SeaBIOS expects coreboot tables at address range 0x0000-0x1000 */
+#define CB_TABLE_ADDR 0x800
+
 /**
  * Function prototype to write a specific configuration table
  *
--
2.28.0.681.g6f77f65b4e-goog

Reply | Threaded
Open this post in threaded view
|

[PATCH 13/32] x86: Use if instead of #ifdef in write_tables()

Simon Glass-3
In reply to this post by Simon Glass-3
Use if() to remove the extra build path in this code.

Signed-off-by: Simon Glass <[hidden email]>
---

 arch/x86/lib/tables.c | 38 +++++++++++++++++++-------------------
 1 file changed, 19 insertions(+), 19 deletions(-)

diff --git a/arch/x86/lib/tables.c b/arch/x86/lib/tables.c
index 43b61a7aeac..62be6746282 100644
--- a/arch/x86/lib/tables.c
+++ b/arch/x86/lib/tables.c
@@ -76,10 +76,8 @@ int write_tables(void)
 {
  u32 rom_table_start = ROM_TABLE_ADDR;
  u32 rom_table_end;
-#ifdef CONFIG_SEABIOS
  u32 high_table, table_size;
  struct memory_area cfg_tables[ARRAY_SIZE(table_list) + 1];
-#endif
  int i;
 
  debug("Writing tables to %x:\n", rom_table_start);
@@ -89,30 +87,32 @@ int write_tables(void)
  rom_table_end = table->write(rom_table_start);
  rom_table_end = ALIGN(rom_table_end, ROM_TABLE_ALIGN);
 
-#ifdef CONFIG_SEABIOS
- table_size = rom_table_end - rom_table_start;
- high_table = (u32)high_table_malloc(table_size);
- if (high_table) {
- table->write(high_table);
-
- cfg_tables[i].start = high_table;
- cfg_tables[i].size = table_size;
- } else {
- printf("%d: no memory for configuration tables\n", i);
- return -ENOSPC;
+ if (IS_ENABLED(CONFIG_SEABIOS)) {
+ table_size = rom_table_end - rom_table_start;
+ high_table = (u32)(ulong)high_table_malloc(table_size);
+ if (high_table) {
+ table->write(high_table);
+
+ cfg_tables[i].start = high_table;
+ cfg_tables[i].size = table_size;
+ } else {
+ printf("%d: no memory for configuration tables\n",
+       i);
+ return -ENOSPC;
+ }
  }
-#endif
 
  debug("- wrote '%s' to %x, end %x\n", table->name,
       rom_table_start, rom_table_end);
  rom_table_start = rom_table_end;
  }
 
-#ifdef CONFIG_SEABIOS
- /* make sure the last item is zero */
- cfg_tables[i].size = 0;
- write_coreboot_table(CB_TABLE_ADDR, cfg_tables);
-#endif
+ if (IS_ENABLED(CONFIG_SEABIOS)) {
+ /* make sure the last item is zero */
+ cfg_tables[i].size = 0;
+ write_coreboot_table(CB_TABLE_ADDR, cfg_tables);
+ }
+
  debug("- done writing tables\n");
 
  return 0;
--
2.28.0.681.g6f77f65b4e-goog

Reply | Threaded
Open this post in threaded view
|

[PATCH 14/32] x86: Allow putting some tables in the bloblist

Simon Glass-3
In reply to this post by Simon Glass-3
At present all tables are placed starting at address f0000 in memory, and
can be up to 64KB in size. If the tables are very large, this may not
provide enough space.

Also if the tables point to other tables (such as console log or a ramoops
area) then we must allocate other memory anyway.

The bloblist is a nice place to put these tables since it is contiguous,
which makes it easy to reserve this memory for linux using the 820 tables.

Add an option to put some of the tables in the bloblist. For SMBIOS and
ACPI, create suitable pointers from the f0000 region to the new location
of the tables.

Signed-off-by: Simon Glass <[hidden email]>
---

 arch/x86/lib/tables.c     | 46 ++++++++++++++++++++++++++++++++++++---
 include/acpi/acpi_table.h | 10 +++++++++
 lib/Kconfig               |  9 ++++++++
 lib/acpi/acpi_table.c     |  4 ++--
 4 files changed, 64 insertions(+), 5 deletions(-)

diff --git a/arch/x86/lib/tables.c b/arch/x86/lib/tables.c
index 62be6746282..db5c45ed3a6 100644
--- a/arch/x86/lib/tables.c
+++ b/arch/x86/lib/tables.c
@@ -4,6 +4,7 @@
  */
 
 #include <common.h>
+#include <bloblist.h>
 #include <log.h>
 #include <malloc.h>
 #include <smbios.h>
@@ -34,10 +35,16 @@ typedef ulong (*table_write)(ulong addr);
  *
  * @name: Name of table (for debugging)
  * @write: Function to call to write this table
+ * @tag: Bloblist tag if using CONFIG_BLOBLIST_TABLES
+ * @size: Maximum table size
+ * @align: Table alignment in bytes
  */
 struct table_info {
  const char *name;
  table_write write;
+ enum bloblist_tag_t tag;
+ int size;
+ int align;
 };
 
 static struct table_info table_list[] = {
@@ -51,10 +58,10 @@ static struct table_info table_list[] = {
  { "mp", write_mp_table, },
 #endif
 #ifdef CONFIG_GENERATE_ACPI_TABLE
- { "acpi", write_acpi_tables, },
+ { "acpi", write_acpi_tables, BLOBLISTT_ACPI_TABLES, 0x10000, 0x1000},
 #endif
 #ifdef CONFIG_GENERATE_SMBIOS_TABLE
- { "smbios", write_smbios_table, },
+ { "smbios", write_smbios_table, BLOBLISTT_SMBIOS_TABLES, 0x1000, 0x100},
 #endif
 };
 
@@ -74,16 +81,25 @@ void table_fill_string(char *dest, const char *src, size_t n, char pad)
 
 int write_tables(void)
 {
- u32 rom_table_start = ROM_TABLE_ADDR;
+ u32 rom_table_start;
  u32 rom_table_end;
  u32 high_table, table_size;
  struct memory_area cfg_tables[ARRAY_SIZE(table_list) + 1];
  int i;
 
+ rom_table_start = ROM_TABLE_ADDR;
+
  debug("Writing tables to %x:\n", rom_table_start);
  for (i = 0; i < ARRAY_SIZE(table_list); i++) {
  const struct table_info *table = &table_list[i];
+ int size = table->size ? : CONFIG_ROM_TABLE_SIZE;
 
+ if (IS_ENABLED(CONFIG_BLOBLIST_TABLES) && table->tag) {
+ rom_table_start = (ulong)bloblist_add(table->tag, size,
+      table->align);
+ if (!rom_table_start)
+ return log_msg_ret("bloblist", -ENOBUFS);
+ }
  rom_table_end = table->write(rom_table_start);
  rom_table_end = ALIGN(rom_table_end, ROM_TABLE_ALIGN);
 
@@ -104,6 +120,11 @@ int write_tables(void)
 
  debug("- wrote '%s' to %x, end %x\n", table->name,
       rom_table_start, rom_table_end);
+ if (rom_table_end - rom_table_start > size) {
+ log_err("Out of space for configuration tables: need %x, have %x\n",
+ rom_table_end - rom_table_start, size);
+ return log_msg_ret("bloblist", -ENOSPC);
+ }
  rom_table_start = rom_table_end;
  }
 
@@ -113,6 +134,25 @@ int write_tables(void)
  write_coreboot_table(CB_TABLE_ADDR, cfg_tables);
  }
 
+ if (IS_ENABLED(CONFIG_BLOBLIST_TABLES)) {
+ struct acpi_ctx *ctx = gd->acpi_ctx;
+ void *ptr = (void *)CONFIG_ROM_TABLE_ADDR;
+
+ /* Write an RSDP pointing to the tables */
+ if (IS_ENABLED(CONFIG_GENERATE_ACPI_TABLE)) {
+ acpi_write_rsdp(ptr, ctx->rsdt, ctx->xsdt);
+ ptr += ALIGN(sizeof(struct acpi_rsdp), 16);
+ }
+ if (IS_ENABLED(CONFIG_GENERATE_SMBIOS_TABLE)) {
+ void *smbios;
+
+ smbios = bloblist_find(BLOBLISTT_SMBIOS_TABLES, 0);
+ if (!smbios)
+ return log_msg_ret("smbios", -ENOENT);
+ memcpy(ptr, smbios, sizeof(struct smbios_entry));
+ }
+ }
+
  debug("- done writing tables\n");
 
  return 0;
diff --git a/include/acpi/acpi_table.h b/include/acpi/acpi_table.h
index abbca6530db..a28eb71f4d7 100644
--- a/include/acpi/acpi_table.h
+++ b/include/acpi/acpi_table.h
@@ -688,6 +688,16 @@ int acpi_add_table(struct acpi_ctx *ctx, void *table);
  */
 void acpi_setup_base_tables(struct acpi_ctx *ctx, void *start);
 
+/**
+ * acpi_write_rsdp() - Write out an RSDP indicating where the ACPI tables are
+ *
+ * @rsdp: Address to write RSDP
+ * @rsdt: Address of RSDT
+ * @xsdt: Address of XSDT
+ */
+void acpi_write_rsdp(struct acpi_rsdp *rsdp, struct acpi_rsdt *rsdt,
+     struct acpi_xsdt *xsdt);
+
 #endif /* !__ACPI__*/
 
 #include <asm/acpi_table.h>
diff --git a/lib/Kconfig b/lib/Kconfig
index 8efb154f734..43fb2ef2ae9 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -624,6 +624,15 @@ config FDT_FIXUP_PARTITIONS
 menu "System tables"
  depends on (!EFI && !SYS_COREBOOT) || (ARM && EFI_LOADER)
 
+config BLOBLIST_TABLES
+ bool "Put tables in a bloblist"
+ depends on X86
+ help
+  Normally tables are placed at address 0xf0000 and can be up to 64KB
+  long. With this option, tables are instead placed in the bloblist
+  with a pointer from 0xf0000. The size can then be larger and the
+  tables can be placed high in memory.
+
 config GENERATE_SMBIOS_TABLE
  bool "Generate an SMBIOS (System Management BIOS) table"
  default y
diff --git a/lib/acpi/acpi_table.c b/lib/acpi/acpi_table.c
index 908d8903893..a0f0961be5b 100644
--- a/lib/acpi/acpi_table.c
+++ b/lib/acpi/acpi_table.c
@@ -183,8 +183,8 @@ int acpi_add_table(struct acpi_ctx *ctx, void *table)
  return 0;
 }
 
-static void acpi_write_rsdp(struct acpi_rsdp *rsdp, struct acpi_rsdt *rsdt,
-    struct acpi_xsdt *xsdt)
+void acpi_write_rsdp(struct acpi_rsdp *rsdp, struct acpi_rsdt *rsdt,
+     struct acpi_xsdt *xsdt)
 {
  memset(rsdp, 0, sizeof(struct acpi_rsdp));
 
--
2.28.0.681.g6f77f65b4e-goog

Reply | Threaded
Open this post in threaded view
|

[PATCH 15/32] x86: nhlt: Correct output of bytes and 16-bit data

Simon Glass-3
In reply to this post by Simon Glass-3
At present these functions are incorrect. Fix them and add some logging
and checking to avoid future problems.

Signed-off-by: Simon Glass <[hidden email]>
---

 arch/x86/lib/acpi_nhlt.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/arch/x86/lib/acpi_nhlt.c b/arch/x86/lib/acpi_nhlt.c
index c64dd9c0081..968e2639f36 100644
--- a/arch/x86/lib/acpi_nhlt.c
+++ b/arch/x86/lib/acpi_nhlt.c
@@ -285,25 +285,26 @@ static void nhlt_free_resources(struct nhlt *nhlt)
 }
 
 struct cursor {
+ u8 *start;
  u8 *buf;
 };
 
 static void ser8(struct cursor *cur, uint val)
 {
  *cur->buf = val;
- cur->buf += sizeof(val);
+ cur->buf += sizeof(u8);
 }
 
 static void ser16(struct cursor *cur, uint val)
 {
  put_unaligned_le16(val, cur->buf);
- cur->buf += sizeof(val);
+ cur->buf += sizeof(u16);
 }
 
 static void ser32(struct cursor *cur, uint val)
 {
  put_unaligned_le32(val, cur->buf);
- cur->buf += sizeof(val);
+ cur->buf += sizeof(u32);
 }
 
 static void serblob(struct cursor *cur, void *from, size_t sz)
@@ -315,12 +316,14 @@ static void serblob(struct cursor *cur, void *from, size_t sz)
 static void serialise_specific_config(struct nhlt_specific_config *cfg,
       struct cursor *cur)
 {
+ log_debug("%x\n", cur->buf - cur->start);
  ser32(cur, cfg->size);
  serblob(cur, cfg->capabilities, cfg->size);
 }
 
 static void serialise_waveform(struct nhlt_waveform *wave, struct cursor *cur)
 {
+ log_debug("%x\n", cur->buf - cur->start);
  ser16(cur, wave->tag);
  ser16(cur, wave->num_channels);
  ser32(cur, wave->samples_per_second);
@@ -338,6 +341,7 @@ static void serialise_waveform(struct nhlt_waveform *wave, struct cursor *cur)
 
 static void serialise_format(struct nhlt_format *fmt, struct cursor *cur)
 {
+ log_debug("%x\n", cur->buf - cur->start);
  serialise_waveform(&fmt->waveform, cur);
  serialise_specific_config(&fmt->config, cur);
 }
@@ -346,6 +350,7 @@ static void serialise_endpoint(struct nhlt_endpoint *endp, struct cursor *cur)
 {
  int i;
 
+ log_debug("%x\n", cur->buf - cur->start);
  ser32(cur, endp->length);
  ser8(cur, endp->link_type);
  ser8(cur, endp->instance_id);
@@ -405,10 +410,12 @@ int nhlt_serialise_oem_overrides(struct acpi_ctx *ctx, struct nhlt *nhlt,
  header->oem_revision = oem_revision;
 
  cur.buf = (void *)(header + 1);
+ cur.start = (void *)header;
  nhlt_serialise_endpoints(nhlt, &cur);
 
  header->checksum = table_compute_checksum(header, sz);
  nhlt_free_resources(nhlt);
+ assert(cur.buf - cur.start == sz);
 
  ret = acpi_add_table(ctx, ctx->current);
  if (ret)
--
2.28.0.681.g6f77f65b4e-goog

Reply | Threaded
Open this post in threaded view
|

[PATCH 16/32] x86: nhlt: Fix a few bugs in the table generation

Simon Glass-3
In reply to this post by Simon Glass-3
At present these tables do not have the correct header, and there is an
occasional incorrect value due to uninited data. Fix these bugs.

Signed-off-by: Simon Glass <[hidden email]>
---

 arch/x86/lib/acpi_nhlt.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/x86/lib/acpi_nhlt.c b/arch/x86/lib/acpi_nhlt.c
index 968e2639f36..dda2af48af4 100644
--- a/arch/x86/lib/acpi_nhlt.c
+++ b/arch/x86/lib/acpi_nhlt.c
@@ -68,6 +68,7 @@ struct nhlt_endpoint *nhlt_add_endpoint(struct nhlt *nhlt, int link_type,
  endp->device_type = device_type;
  endp->direction = dir;
  endp->virtual_bus_id = DEFAULT_VIRTUAL_BUS_ID;
+ endp->num_formats = 0;
 
  nhlt->num_endpoints++;
 
@@ -395,7 +396,7 @@ int nhlt_serialise_oem_overrides(struct acpi_ctx *ctx, struct nhlt *nhlt,
  /* Create header */
  header = (void *)ctx->current;
  memset(header, '\0', sizeof(struct acpi_table_header));
- acpi_fill_header(header, "NHLT");
+ memcpy(header->signature, "NHLT", 4);
  header->length = sz;
  header->revision = acpi_get_table_revision(ACPITAB_NHLT);
 
@@ -408,6 +409,7 @@ int nhlt_serialise_oem_overrides(struct acpi_ctx *ctx, struct nhlt *nhlt,
  memcpy(header->oem_table_id, oem_table_id, oem_table_id_len);
  }
  header->oem_revision = oem_revision;
+ memcpy(header->aslc_id, ASLC_ID, 4);
 
  cur.buf = (void *)(header + 1);
  cur.start = (void *)header;
--
2.28.0.681.g6f77f65b4e-goog

Reply | Threaded
Open this post in threaded view
|

[PATCH 17/32] x86: Show the interrupt pointer with 'irqinfo'

Simon Glass-3
In reply to this post by Simon Glass-3
It is useful for this command to show the address of the interrupt table.
Add support for this.

Signed-off-by: Simon Glass <[hidden email]>
---

 arch/x86/cpu/i386/interrupt.c    | 14 +++++++-------
 arch/x86/include/asm/interrupt.h | 17 +++++++++++++++++
 arch/x86/lib/interrupts.c        |  3 +++
 3 files changed, 27 insertions(+), 7 deletions(-)

diff --git a/arch/x86/cpu/i386/interrupt.c b/arch/x86/cpu/i386/interrupt.c
index c0c4bc95fd9..d85f84b29a7 100644
--- a/arch/x86/cpu/i386/interrupt.c
+++ b/arch/x86/cpu/i386/interrupt.c
@@ -180,16 +180,11 @@ struct idt_entry {
  u16 base_high;
 } __packed;
 
-struct desc_ptr {
- unsigned short size;
- unsigned long address;
-} __packed;
-
 struct idt_entry idt[256] __aligned(16);
 
-struct desc_ptr idt_ptr;
+struct idt_ptr idt_ptr;
 
-static inline void load_idt(const struct desc_ptr *dtr)
+static inline void load_idt(const struct idt_ptr *dtr)
 {
  asm volatile("cs lidt %0" : : "m" (*dtr));
 }
@@ -232,6 +227,11 @@ int cpu_init_interrupts(void)
  return 0;
 }
 
+void interrupt_read_idt(struct idt_ptr *ptr)
+{
+ asm volatile("sidt %0" : : "m" (*ptr));
+}
+
 void *x86_get_idt(void)
 {
  return &idt_ptr;
diff --git a/arch/x86/include/asm/interrupt.h b/arch/x86/include/asm/interrupt.h
index fdeb8571132..e23fb2c8e72 100644
--- a/arch/x86/include/asm/interrupt.h
+++ b/arch/x86/include/asm/interrupt.h
@@ -38,6 +38,16 @@ enum x86_exception {
  EXC_VE
 };
 
+/**
+ * struct idt_ptr - Holds the IDT (Interrupt Descriptor Table)
+ *
+ * @size: Size of IDT in bytes
+ */
+struct idt_ptr {
+ unsigned short size;
+ unsigned long address;
+} __packed;
+
 /* arch/x86/cpu/interrupts.c */
 void set_vector(u8 intnum, void *routine);
 
@@ -61,4 +71,11 @@ void configure_irq_trigger(int int_num, bool is_level_triggered);
 
 void *x86_get_idt(void);
 
+/**
+ * interrupt_read_idt() - Read the IDT
+ *
+ * @ptr: Place to put IDT contents
+ */
+void interrupt_read_idt(struct idt_ptr *ptr);
+
 #endif
diff --git a/arch/x86/lib/interrupts.c b/arch/x86/lib/interrupts.c
index a81e4291105..ff52959ed28 100644
--- a/arch/x86/lib/interrupts.c
+++ b/arch/x86/lib/interrupts.c
@@ -131,8 +131,11 @@ void do_irq(int hw_irq)
 int do_irqinfo(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
 {
 #if !CONFIG_IS_ENABLED(X86_64)
+ struct idt_ptr ptr;
  int irq;
 
+ interrupt_read_idt(&ptr);
+ printf("IDT at %lx, size %x\n", ptr.address, ptr.size);
  printf("Spurious IRQ: %u, last unknown IRQ: %d\n",
  spurious_irq_cnt, spurious_irq);
 
--
2.28.0.681.g6f77f65b4e-goog

Reply | Threaded
Open this post in threaded view
|

[PATCH 18/32] x86: sound: Correct error handling

Simon Glass-3
In reply to this post by Simon Glass-3
A few functions have changed to return pin numbers or I2C addresses. The
error checking for some of the callers is therefore wrong. Fix them.

Signed-off-by: Simon Glass <[hidden email]>
---

 drivers/sound/da7219.c    | 4 ++--
 drivers/sound/max98357a.c | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/sound/da7219.c b/drivers/sound/da7219.c
index 6bc1ad0036e..8d674bcb4fa 100644
--- a/drivers/sound/da7219.c
+++ b/drivers/sound/da7219.c
@@ -54,13 +54,13 @@ static int da7219_acpi_fill_ssdt(const struct udevice *dev,
  acpigen_write_name(ctx, "_CRS");
  acpigen_write_resourcetemplate_header(ctx);
  ret = acpi_device_write_i2c_dev(ctx, dev);
- if (ret)
+ if (ret < 0)
  return log_msg_ret("i2c", ret);
 
  /* Use either Interrupt() or GpioInt() */
  ret = acpi_device_write_interrupt_or_gpio(ctx, (struct udevice *)dev,
   "req-gpios");
- if (ret)
+ if (ret < 0)
  return log_msg_ret("irq_gpio", ret);
  acpigen_write_resourcetemplate_footer(ctx);
 
diff --git a/drivers/sound/max98357a.c b/drivers/sound/max98357a.c
index 827262d235c..b3d27a3616e 100644
--- a/drivers/sound/max98357a.c
+++ b/drivers/sound/max98357a.c
@@ -69,7 +69,7 @@ static int max98357a_acpi_fill_ssdt(const struct udevice *dev,
  acpigen_write_name(ctx, "_CRS");
  acpigen_write_resourcetemplate_header(ctx);
  ret = acpi_device_write_gpio_desc(ctx, &priv->sdmode_gpio);
- if (ret)
+ if (ret < 0)
  return log_msg_ret("gpio", ret);
  acpigen_write_resourcetemplate_footer(ctx);
 
--
2.28.0.681.g6f77f65b4e-goog

Reply | Threaded
Open this post in threaded view
|

[PATCH 19/32] acpi: Correct reset handling in acpi_device_add_power_res()

Simon Glass-3
In reply to this post by Simon Glass-3
If there is no reset line, this still emits ACPI code for the reset GPIO.
Fix it by updating the check.

Signed-off-by: Simon Glass <[hidden email]>
---

 lib/acpi/acpi_device.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/acpi/acpi_device.c b/lib/acpi/acpi_device.c
index 95dfac583fc..c3439a59883 100644
--- a/lib/acpi/acpi_device.c
+++ b/lib/acpi/acpi_device.c
@@ -422,7 +422,7 @@ int acpi_device_add_power_res(struct acpi_ctx *ctx, u32 tx_state_val,
 
  /* Method (_ON, 0, Serialized) */
  acpigen_write_method_serialized(ctx, "_ON", 0);
- if (reset_gpio) {
+ if (has_reset) {
  ret = acpigen_set_enable_tx_gpio(ctx, tx_state_val, dw0_read,
  dw0_write, &reset, true);
  if (ret)
--
2.28.0.681.g6f77f65b4e-goog

1234