Furquan Shaikh (furquan(a)google.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/17089
-gerrit
commit 45b0f42c8918749c4a3dd4711f47bea2183c1a69
Author: Furquan Shaikh <furquan(a)chromium.org>
Date: Fri Oct 21 16:24:07 2016 -0700
drivers/i2c/generic: Re-factor SSDT generation code
1. Export i2c_generic_fill_ssdt to allow other device-specific i2c
drivers to share and re-use the same code for generating AML code for
SSDT. In order to achieve this, following changes are required:
a. Add macro I2C_GENERIC_CONFIG that defines a structure with all
generic i2c device-tree properties. This macro should be placed by the
using driver at the start of its config structure.
b. Accept a callback function to add any device specific information to
SSDT. If generic driver is used directly by a device, callback would be
NULL. Other devices using a separate i2c driver can provide a callback
to add any properties to SSDT.
2. Allow device to provide _CID.
BUG=chrome-os-partner:57846
Change-Id: I3a0054e22b81f9d6d407bef417eae5e9edc04ee4
Signed-off-by: Furquan Shaikh <furquan(a)chromium.org>
---
src/drivers/i2c/generic/chip.h | 33 +++++++++++++++++++++++++++++++++
src/drivers/i2c/generic/generic.c | 16 ++++++++++++++--
2 files changed, 47 insertions(+), 2 deletions(-)
diff --git a/src/drivers/i2c/generic/chip.h b/src/drivers/i2c/generic/chip.h
index e84fc38..736de51 100644
--- a/src/drivers/i2c/generic/chip.h
+++ b/src/drivers/i2c/generic/chip.h
@@ -1,8 +1,27 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2016 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __I2C_GENERIC_CHIP_H__
+#define __I2C_GENERIC_CHIP_H__
+
#include <arch/acpi_device.h>
#include <device/i2c.h>
struct drivers_i2c_generic_config {
const char *hid; /* ACPI _HID (required) */
+ const char *cid; /* ACPI _CID */
const char *name; /* ACPI Device Name */
const char *desc; /* Device Description */
unsigned uid; /* ACPI _UID */
@@ -32,3 +51,17 @@ struct drivers_i2c_generic_config {
/* Delay to be inserted after device is enabled. */
unsigned enable_delay_ms;
};
+
+/*
+ * Fills in generic information about i2c device from device-tree
+ * properties. Callback can be provided to fill in any
+ * device-specific information in SSDT.
+ *
+ * Drivers calling into this function to generate should place
+ * drivers_i2c_generic_config structure at the beginning of their device config
+ * structure.
+ */
+void i2c_generic_fill_ssdt(struct device *dev,
+ void (*callback)(struct device *dev));
+
+#endif /* __I2C_GENERIC_CHIP_H__ */
diff --git a/src/drivers/i2c/generic/generic.c b/src/drivers/i2c/generic/generic.c
index bf40a2a..83b0953 100644
--- a/src/drivers/i2c/generic/generic.c
+++ b/src/drivers/i2c/generic/generic.c
@@ -65,7 +65,8 @@ static void i2c_generic_add_power_res(struct drivers_i2c_generic_config *config)
acpigen_pop_len(); /* PowerResource PRIC */
}
-static void i2c_generic_fill_ssdt(struct device *dev)
+void i2c_generic_fill_ssdt(struct device *dev,
+ void (*callback)(struct device *dev))
{
struct drivers_i2c_generic_config *config = dev->chip_info;
const char *scope = acpi_device_scope(dev);
@@ -89,6 +90,8 @@ static void i2c_generic_fill_ssdt(struct device *dev)
acpigen_write_scope(scope);
acpigen_write_device(acpi_device_name(dev));
acpigen_write_name_string("_HID", config->hid);
+ if (config->cid)
+ acpigen_write_name_string("_CID", config->cid);
acpigen_write_name_integer("_UID", config->uid);
acpigen_write_name_string("_DDN", config->desc);
acpigen_write_STA(ACPI_STATUS_DEVICE_ALL_ON);
@@ -115,6 +118,10 @@ static void i2c_generic_fill_ssdt(struct device *dev)
/* Power Resource */
i2c_generic_add_power_res(config);
+ /* Callback if any. */
+ if (callback)
+ callback(dev);
+
acpigen_pop_len(); /* Device */
acpigen_pop_len(); /* Scope */
@@ -122,6 +129,11 @@ static void i2c_generic_fill_ssdt(struct device *dev)
config->desc ? : dev->chip_ops->name, dev_path(dev));
}
+static void i2c_generic_fill_ssdt_generator(struct device *dev)
+{
+ i2c_generic_fill_ssdt(dev, NULL);
+}
+
/* Use name specified in config or build one from I2C address */
static const char *i2c_generic_acpi_name(struct device *dev)
{
@@ -143,7 +155,7 @@ static struct device_operations i2c_generic_ops = {
.enable_resources = DEVICE_NOOP,
#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES)
.acpi_name = &i2c_generic_acpi_name,
- .acpi_fill_ssdt_generator = &i2c_generic_fill_ssdt,
+ .acpi_fill_ssdt_generator = &i2c_generic_fill_ssdt_generator,
#endif
};
Furquan Shaikh (furquan(a)google.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/17092
-gerrit
commit ad84dc38bd9669c0d783ff034828bb4a0a8b28ca
Author: Furquan Shaikh <furquan(a)chromium.org>
Date: Fri Oct 21 16:42:45 2016 -0700
drivers/i2c/wacom_ts: Add support for WCOM touchscreen device driver
BUG=chrome-os-partner:57846
Change-Id: Id6bd91b3fd6420994ad5811d362618b1a38a8afa
Signed-off-by: Furquan Shaikh <furquan(a)chromium.org>
---
src/drivers/i2c/wacom_ts/Kconfig | 3 ++
src/drivers/i2c/wacom_ts/Makefile.inc | 1 +
src/drivers/i2c/wacom_ts/chip.h | 30 ++++++++++++++++
src/drivers/i2c/wacom_ts/ts.c | 65 +++++++++++++++++++++++++++++++++++
4 files changed, 99 insertions(+)
diff --git a/src/drivers/i2c/wacom_ts/Kconfig b/src/drivers/i2c/wacom_ts/Kconfig
new file mode 100644
index 0000000..50da3f1
--- /dev/null
+++ b/src/drivers/i2c/wacom_ts/Kconfig
@@ -0,0 +1,3 @@
+config DRIVERS_I2C_WACOM_TS
+ bool
+ select DRIVERS_I2C_GENERIC
diff --git a/src/drivers/i2c/wacom_ts/Makefile.inc b/src/drivers/i2c/wacom_ts/Makefile.inc
new file mode 100644
index 0000000..9455099
--- /dev/null
+++ b/src/drivers/i2c/wacom_ts/Makefile.inc
@@ -0,0 +1 @@
+ramstage-$(CONFIG_DRIVERS_I2C_WACOM_TS) += ts.c
diff --git a/src/drivers/i2c/wacom_ts/chip.h b/src/drivers/i2c/wacom_ts/chip.h
new file mode 100644
index 0000000..b59f630
--- /dev/null
+++ b/src/drivers/i2c/wacom_ts/chip.h
@@ -0,0 +1,30 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2016 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __I2C_WACOM_TS_CHIP_H__
+#define __I2C_WACOM_TS_CHIP_H__
+
+#include <drivers/i2c/generic/chip.h>
+
+#define WCOM50C1_HID "WCOM50C1"
+#define PNP0C50_CID "PNP0C50"
+#define WCOM_TS_DESC "WCOM Touchscreen"
+
+struct drivers_i2c_wacom_ts_config {
+ struct drivers_i2c_generic_config generic;
+ uint8_t hid_desc_reg_offset;
+};
+
+#endif /* __I2C_WACOM_TS_CHIP_H__ */
diff --git a/src/drivers/i2c/wacom_ts/ts.c b/src/drivers/i2c/wacom_ts/ts.c
new file mode 100644
index 0000000..8757ccc
--- /dev/null
+++ b/src/drivers/i2c/wacom_ts/ts.c
@@ -0,0 +1,65 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2016 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <arch/acpi_device.h>
+#include <arch/acpigen.h>
+#include <arch/acpigen_dsm.h>
+#include <console/console.h>
+#include <device/i2c.h>
+#include <device/device.h>
+#include <device/path.h>
+#include <stdint.h>
+#include <string.h>
+#include "chip.h"
+
+static void i2c_wacom_ts_fill_dsm(struct device *dev)
+{
+ struct drivers_i2c_wacom_ts_config *config = dev->chip_info;
+ struct dsm_i2c_hid_config dsm_config = {
+ .hid_desc_reg_offset = config->hid_desc_reg_offset,
+ };
+
+ acpigen_write_dsm_i2c_hid(&dsm_config);
+}
+
+static void i2c_wacom_ts_fill_ssdt_generator(struct device *dev)
+{
+ i2c_generic_fill_ssdt(dev, &i2c_wacom_ts_fill_dsm);
+}
+
+static const char *i2c_wacom_ts_acpi_name(struct device *dev)
+{
+ return "WCTS";
+}
+
+static struct device_operations i2c_wacom_ts_ops = {
+ .read_resources = DEVICE_NOOP,
+ .set_resources = DEVICE_NOOP,
+ .enable_resources = DEVICE_NOOP,
+#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES)
+ .acpi_name = &i2c_wacom_ts_acpi_name,
+ .acpi_fill_ssdt_generator = &i2c_wacom_ts_fill_ssdt_generator,
+#endif
+};
+
+static void i2c_wacom_ts_enable(struct device *dev)
+{
+ dev->ops = &i2c_wacom_ts_ops;
+}
+
+struct chip_operations drivers_i2c_wacom_ts_ops = {
+ CHIP_NAME("Wacom Touchscreen Device")
+ .enable_dev = &i2c_wacom_ts_enable
+};
Furquan Shaikh (furquan(a)google.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/17080
-gerrit
commit 139e272fa560c3262802c85fefc08b66374ff2b1
Author: Furquan Shaikh <furquan(a)chromium.org>
Date: Thu Oct 20 07:12:49 2016 -0700
arch/x86/acpigen: Add support for interacting with GPIOs
Since reading/toggling of GPIOs is platform-dependent task, provide an
interface with common functions to generate ACPI AML code for
manipulating GPIOs:
1. acpigen_soc_read_rx_gpio
2. acpigen_soc_get_tx_gpio
3. acpigen_soc_set_tx_gpio
4. acpigen_soc_clear_tx_gpio
Provide weak implementations of above functions. These functions are
expected to be implemented by every SoC that uses ACPI. This allows
drivers to easily generate ACPI AML code to interact GPIOs.
BUG=chrome-os-partner:55988
Change-Id: I3564f15a1cb50e6ca6132638447529648589aa0e
Signed-off-by: Furquan Shaikh <furquan(a)chromium.org>
---
src/arch/x86/acpigen.c | 29 +++++++++++++++++++++++++++++
src/arch/x86/include/arch/acpigen.h | 22 ++++++++++++++++++++++
2 files changed, 51 insertions(+)
diff --git a/src/arch/x86/acpigen.c b/src/arch/x86/acpigen.c
index e0e957a..0a57263 100644
--- a/src/arch/x86/acpigen.c
+++ b/src/arch/x86/acpigen.c
@@ -992,3 +992,32 @@ void acpigen_write_else(void)
acpigen_emit_byte(ELSE_OP);
acpigen_write_len_f();
}
+
+/* Soc-implemented functions -- weak definitions. */
+int __attribute__((weak)) acpigen_soc_read_rx_gpio(unsigned int gpio_num)
+{
+ printk(BIOS_ERR, "ERROR: %s not implemented\n", __func__);
+ acpigen_write_debug_string("read_rx_gpio not available");
+ return -1;
+}
+
+int __attribute__((weak)) acpigen_soc_get_tx_gpio(unsigned int gpio_num)
+{
+ printk(BIOS_ERR, "ERROR: %s not implemented\n", __func__);
+ acpigen_write_debug_string("get_tx_gpio not available");
+ return -1;
+}
+
+int __attribute__((weak)) acpigen_soc_set_tx_gpio(unsigned int gpio_num)
+{
+ printk(BIOS_ERR, "ERROR: %s not implemented\n", __func__);
+ acpigen_write_debug_string("set_tx_gpio not available");
+ return -1;
+}
+
+int __attribute__((weak)) acpigen_soc_clear_tx_gpio(unsigned int gpio_num)
+{
+ printk(BIOS_ERR, "ERROR: %s not implemented\n", __func__);
+ acpigen_write_debug_string("clear_tx_gpio not available");
+ return -1;
+}
diff --git a/src/arch/x86/include/arch/acpigen.h b/src/arch/x86/include/arch/acpigen.h
index c2936e2..0c515da 100644
--- a/src/arch/x86/include/arch/acpigen.h
+++ b/src/arch/x86/include/arch/acpigen.h
@@ -160,4 +160,26 @@ void acpigen_write_else(void);
int get_cst_entries(acpi_cstate_t **);
+/*
+ * Soc-implemented functions for generating ACPI AML code for GPIO handling. All
+ * these functions are expected to use only Local5, Local6 and Local7
+ * variables. If the functions call into another ACPI method, then there is no
+ * restriction on the use of Local variables. In case of get/read functions,
+ * return value is expected to be stored in Local0 variable.
+ *
+ * All functions return 0 on success and -1 on error.
+ */
+
+/* Generate ACPI AML code to return Rx value of GPIO in Local0. */
+int acpigen_soc_read_rx_gpio(unsigned int gpio_num);
+
+/* Generate ACPI AML code to return Tx value of GPIO in Local0. */
+int acpigen_soc_get_tx_gpio(unsigned int gpio_num);
+
+/* Generate ACPI AML code to set Tx value of GPIO to 1. */
+int acpigen_soc_set_tx_gpio(unsigned int gpio_num);
+
+/* Generate ACPI AML code to set Tx value of GPIO to 0. */
+int acpigen_soc_clear_tx_gpio(unsigned int gpio_num);
+
#endif
Furquan Shaikh (furquan(a)google.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/17083
-gerrit
commit 6728ce3fdf8b9fbab0ac103dd6eb4c3045549d79
Author: Furquan Shaikh <furquan(a)chromium.org>
Date: Thu Oct 20 22:48:45 2016 -0700
mainboard/google/reef: Add PowerResource for ELAN touchscreen
Define reset_gpio and enable_gpio for touchscreen device so that when
kernel puts this device into D3, we put the device into
reset. PowerResource _ON and _OFF routines are used to put the device
into D0 and D3 states.
BUG=chrome-os-partner:55988
Change-Id: Ia905f9eb630cd96767b639aec74131dbd7952d0e
Signed-off-by: Furquan Shaikh <furquan(a)chromium.org>
---
src/mainboard/google/reef/variants/baseboard/devicetree.cb | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/mainboard/google/reef/variants/baseboard/devicetree.cb b/src/mainboard/google/reef/variants/baseboard/devicetree.cb
index 00df9bd..30d61f6 100644
--- a/src/mainboard/google/reef/variants/baseboard/devicetree.cb
+++ b/src/mainboard/google/reef/variants/baseboard/devicetree.cb
@@ -142,6 +142,10 @@ chip soc/intel/apollolake
register "desc" = ""ELAN Touchscreen""
register "irq" = "IRQ_EDGE_LOW(GPIO_21_IRQ)"
register "probed" = "1"
+ register "reset_gpio" = "GPIO_36"
+ register "reset_delay_ms" = "20"
+ register "enable_gpio" = "GPIO_152"
+ register "enable_delay_ms" = "1"
device i2c 10 on end
end
end # - I2C 3
Brenton Dong (brenton.m.dong(a)intel.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/17063
-gerrit
commit ef2b9f9ce3f465de172617956553419c3bf2eaaa
Author: Brenton Dong <brenton.m.dong(a)intel.com>
Date: Tue Oct 18 13:57:54 2016 -0700
soc/intel/apollolake: allow ApolloLake SoC to use FSP CAR Init
FSP v2.0 Driver supports TempRamInit & TempRamExit APIs to initialize
& tear down Cache-As-Ram. Add TempRamInit & TempRamExit usage to
ApolloLake SoC when CONFIG_FSP_CAR is enabled.
Verified on Intel Leaf Hill CRB and confirmed that Cache-As-Ram
is correctly set up and torn down using the FSP v2.0 APIs
without coreboot implementation of CAR init/teardown.
Change-Id: Ifd6fe8398ea147a5fb8c60076b93205bb94b1f25
Signed-off-by: Brenton Dong <brenton.m.dong(a)intel.com>
---
src/soc/intel/apollolake/Makefile.inc | 15 +++-
.../intel/apollolake/bootblock/cache_as_ram_fsp.S | 98 ++++++++++++++++++++++
src/soc/intel/apollolake/exit_car_fsp.S | 29 +++++++
src/soc/intel/apollolake/include/soc/postcar.h | 26 ++++++
src/soc/intel/apollolake/postcar.c | 34 ++++++++
5 files changed, 200 insertions(+), 2 deletions(-)
diff --git a/src/soc/intel/apollolake/Makefile.inc b/src/soc/intel/apollolake/Makefile.inc
index 4f867e1..b4a79f0 100644
--- a/src/soc/intel/apollolake/Makefile.inc
+++ b/src/soc/intel/apollolake/Makefile.inc
@@ -9,7 +9,6 @@ subdirs-y += ../../../cpu/x86/tsc
subdirs-y += ../../../cpu/x86/cache
bootblock-y += bootblock/bootblock.c
-bootblock-y += bootblock/cache_as_ram.S
bootblock-y += bootblock/bootblock.c
bootblock-y += car.c
bootblock-y += gpio.c
@@ -22,6 +21,12 @@ bootblock-y += spi.c
bootblock-y += tsc_freq.c
bootblock-$(CONFIG_SOC_UART_DEBUG) += uart_early.c
+ifeq ($(CONFIG_FSP_CAR),y)
+bootblock-y += bootblock/cache_as_ram_fsp.S
+else
+bootblock-y += bootblock/cache_as_ram.S
+endif
+
romstage-y += car.c
romstage-$(CONFIG_PLATFORM_USES_FSP2_0) += romstage.c
romstage-y += gpio.c
@@ -75,13 +80,19 @@ ramstage-y += sram.c
ramstage-y += spi.c
ramstage-y += xhci.c
-postcar-y += exit_car.S
postcar-y += memmap.c
postcar-y += mmap_boot.c
postcar-y += spi.c
postcar-$(CONFIG_SOC_UART_DEBUG) += uart_early.c
postcar-y += tsc_freq.c
+ifeq ($(CONFIG_FSP_CAR),y)
+postcar-y += exit_car_fsp.S
+postcar-y += postcar.c
+else
+postcar-y += exit_car.S
+endif
+
verstage-y += car.c
verstage-y += i2c_early.c
verstage-y += heci.c
diff --git a/src/soc/intel/apollolake/bootblock/cache_as_ram_fsp.S b/src/soc/intel/apollolake/bootblock/cache_as_ram_fsp.S
new file mode 100755
index 0000000..779cfeb
--- /dev/null
+++ b/src/soc/intel/apollolake/bootblock/cache_as_ram_fsp.S
@@ -0,0 +1,98 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015-2016 Intel Corp.
+ * (Written by Andrey Petrov <andrey.petrov(a)intel.com> for Intel Corp.)
+ * (Written by Alexandru Gagniuc <alexandrux.gagniuc(a)intel.com> for Intel Corp.)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <device/pci_def.h>
+#include <cpu/x86/mtrr.h>
+#include <cpu/x86/cache.h>
+#include <cpu/x86/cr.h>
+#include <cpu/x86/post_code.h>
+#include <soc/cpu.h>
+
+#include <../../../arch/x86/walkcbfs.S>
+
+.global bootblock_pre_c_entry
+bootblock_pre_c_entry:
+
+.global cache_as_ram
+cache_as_ram:
+ post_code(0x21)
+
+ /* find fsp in cbfs */
+ lea fsp_name, %esi
+ mov $1f, %esp
+ jmp walkcbfs_asm
+1:
+ cmp $0, %eax
+ jz .halt_forever
+ mov CBFS_FILE_OFFSET(%eax), %ebx
+ bswap %ebx
+ add %eax, %ebx
+ add $0x94, %ebx
+
+ /*
+ * ebx = FSP INFO HEADER
+ * Calculate entry into FSP
+ */
+ mov 0x30(%ebx), %eax /* Load TempRamInitEntry */
+ add 0x1c(%ebx), %eax /* add in the offset for FSP */
+
+ /*
+ * Pass early init variables on a fake stack (no memory yet)
+ * as well as the return location
+ */
+ lea CAR_init_stack, %esp
+
+ /* call FSP binary to setup temporary stack */
+ jmp *%eax
+
+CAR_init_done:
+
+ /* Setup bootblock stack */
+ mov %edx, %esp
+
+ /* clear CAR_GLOBAL area as it is not shared */
+ cld
+ xor %eax, %eax
+ movl $(_car_global_end), %ecx
+ movl $(_car_global_start), %edi
+ sub %edi, %ecx
+ rep stosl
+ nop
+
+ /* We can call into C functions now */
+ call bootblock_c_entry
+
+ /* Never reached */
+
+.halt_forever:
+ post_code(POST_DEAD_CODE)
+ hlt
+ jmp .halt_forever
+
+CAR_init_params:
+ .long 0xFFFFFFFF - CONFIG_ROM_SIZE + 1 /* Microcode Location */
+ .long 0 /* Microcode Length */
+ .long 0xFFFFFFFF - CONFIG_IBBL_ROM_SIZE + 1 /* Firmware Location */
+ .long CONFIG_IBBL_ROM_SIZE /* Total Firmware Length */
+
+CAR_init_stack:
+ .long CAR_init_done
+ .long CAR_init_params
+
+fsp_name:
+ .ascii "blobs/fspt.bin\x00"
diff --git a/src/soc/intel/apollolake/exit_car_fsp.S b/src/soc/intel/apollolake/exit_car_fsp.S
new file mode 100644
index 0000000..122d5ca
--- /dev/null
+++ b/src/soc/intel/apollolake/exit_car_fsp.S
@@ -0,0 +1,29 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2016 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <cpu/x86/mtrr.h>
+#include <cpu/x86/cr.h>
+#include <soc/cpu.h>
+
+.text
+.global chipset_teardown_car
+chipset_teardown_car:
+
+ /* Set up new stack. */
+ mov $CONFIG_RAMTOP, %esp
+
+ /* Call C code */
+ call post_car_main
diff --git a/src/soc/intel/apollolake/include/soc/postcar.h b/src/soc/intel/apollolake/include/soc/postcar.h
new file mode 100644
index 0000000..7e31def
--- /dev/null
+++ b/src/soc/intel/apollolake/include/soc/postcar.h
@@ -0,0 +1,26 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 Intel Corp.
+ * (Written by Andrey Petrov <andrey.petrov(a)intel.com> for Intel Corp.)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _SOC_APOLLOLAKE_POSTCAR_H_
+#define _SOC_APOLLOLAKE_POSTCAR_H_
+
+#include <arch/cpu.h>
+#include <fsp/api.h>
+
+void post_car_main(void);
+
+#endif /* _SOC_APOLLOLAKE_POSTCAR_H_ */
diff --git a/src/soc/intel/apollolake/postcar.c b/src/soc/intel/apollolake/postcar.c
new file mode 100644
index 0000000..0b0e4ca
--- /dev/null
+++ b/src/soc/intel/apollolake/postcar.c
@@ -0,0 +1,34 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 Intel Corp.
+ * (Written by Alexandru Gagniuc <alexandrux.gagniuc(a)intel.com> for Intel Corp.)
+ * (Written by Andrey Petrov <andrey.petrov(a)intel.com> for Intel Corp.)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <string.h>
+#include <cbmem.h>
+#include <arch/cpu.h>
+#include <arch/stages.h>
+#include <fsp/util.h>
+#include <soc/postcar.h>
+#include <boot_device.h>
+
+void post_car_main(void)
+{
+ temp_ram_exit();
+
+ /* Recover cbmem so infrastruture using it is functional. */
+ cbmem_initialize();
+
+ copy_and_run();
+}