Furquan Shaikh (furquan(a)google.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/18342
-gerrit
commit f2116a6a2abb9b8b18e5c737592b765df357864f
Author: Furquan Shaikh <furquan(a)chromium.org>
Date: Sat Feb 11 11:16:18 2017 -0800
drivers/spi: Add support for generating SPI device in SSDT
Similar to I2C driver, add support for generating SPI device and
required properties in SSDT for ACPI.
BUG=chrome-os-partner:59832
BRANCH=None
TEST=Compiles succesfully. Verified SPI device generated in SSDT on
poppy.
Change-Id: Ic4da79c823131d54d9eb3652b86f6e40fe643ab5
Signed-off-by: Furquan Shaikh <furquan(a)chromium.org>
---
src/drivers/spi/acpi/Kconfig | 18 +++++
src/drivers/spi/acpi/Makefile.inc | 16 +++++
src/drivers/spi/acpi/acpi.c | 147 ++++++++++++++++++++++++++++++++++++++
src/drivers/spi/acpi/chip.h | 32 +++++++++
4 files changed, 213 insertions(+)
diff --git a/src/drivers/spi/acpi/Kconfig b/src/drivers/spi/acpi/Kconfig
new file mode 100644
index 0000000..c1653d5
--- /dev/null
+++ b/src/drivers/spi/acpi/Kconfig
@@ -0,0 +1,18 @@
+#
+# This file is part of the coreboot project.
+#
+# Copyright 2017 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.
+#
+
+config DRIVERS_SPI_ACPI
+ bool
+ depends on HAVE_ACPI_TABLES
diff --git a/src/drivers/spi/acpi/Makefile.inc b/src/drivers/spi/acpi/Makefile.inc
new file mode 100644
index 0000000..7ae6e45
--- /dev/null
+++ b/src/drivers/spi/acpi/Makefile.inc
@@ -0,0 +1,16 @@
+#
+# This file is part of the coreboot project.
+#
+# Copyright 2017 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.
+#
+
+ramstage-$(CONFIG_DRIVERS_SPI_ACPI) += acpi.c
diff --git a/src/drivers/spi/acpi/acpi.c b/src/drivers/spi/acpi/acpi.c
new file mode 100644
index 0000000..1c18ed4
--- /dev/null
+++ b/src/drivers/spi/acpi/acpi.c
@@ -0,0 +1,147 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2017 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 <console/console.h>
+#include <device/device.h>
+#include <device/path.h>
+#include <device/spi.h>
+#include <spi-generic.h>
+#include <stdint.h>
+#include <string.h>
+#include "chip.h"
+
+static int spi_acpi_get_bus(struct device *dev)
+{
+ struct device *spi_dev;
+ struct device_operations *ops;
+
+ if (!dev->bus || !dev->bus->dev)
+ return -1;
+
+ spi_dev = dev->bus->dev;
+ ops = spi_dev->ops;
+
+ if (ops && ops->ops_spi_bus &&
+ ops->ops_spi_bus->dev_to_bus)
+ return ops->ops_spi_bus->dev_to_bus(spi_dev);
+
+ return -1;
+}
+
+static void spi_acpi_fill_ssdt_generator(struct device *dev)
+{
+ struct drivers_spi_acpi_config *config = dev->chip_info;
+ const char *scope = acpi_device_scope(dev);
+ struct acpi_dp *dsd = NULL;
+ struct spi_cfg spi_cfg;
+ struct spi_slave slave;
+ int bus = -1, cs = dev->path.spi.cs;
+ struct acpi_spi spi = {
+ .device_select = cs,
+ .speed = config->speed,
+ .resource = scope,
+ };
+
+ if (!dev->enabled || !scope)
+ return;
+
+ bus = spi_acpi_get_bus(dev);
+ if (bus == -1) {
+ printk(BIOS_ERR, "%s: ERROR: Cannot get bus for device.\n",
+ dev_path(dev));
+ return;
+ }
+
+ if (!config->hid) {
+ printk(BIOS_ERR, "%s: ERROR: HID required.\n", dev_path(dev));
+ return;
+ }
+
+ if (spi_setup_slave(bus, cs, &slave)) {
+ printk(BIOS_ERR, "%s: ERROR: SPI setup failed.\n",
+ dev_path(dev));
+ return;
+ }
+
+ if (spi_get_config(&slave, &spi_cfg)) {
+ printk(BIOS_ERR, "%s: ERROR: SPI get config failed.\n",
+ dev_path(dev));
+ return;
+ }
+
+ spi.device_select_polarity = spi_cfg.cs_polarity;
+ spi.wire_mode = spi_cfg.wire_mode;
+ spi.data_bit_length = spi_cfg.data_bit_length;
+ spi.clock_phase = spi_cfg.clk_phase;
+
+ /* Device */
+ 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);
+ if (config->desc)
+ acpigen_write_name_string("_DDN", config->desc);
+
+ /* Resources */
+ acpigen_write_name("_CRS");
+ acpigen_write_resourcetemplate_header();
+ acpi_device_write_spi(&spi);
+ acpi_device_write_interrupt(&config->irq);
+ acpigen_write_resourcetemplate_footer();
+
+ if (config->compat_string) {
+ dsd = acpi_dp_new_table("_DSD");
+ acpi_dp_add_string(dsd, "compatible", config->compat_string);
+ acpi_dp_write(dsd);
+ }
+
+ acpigen_pop_len(); /* Device */
+ acpigen_pop_len(); /* Scope */
+}
+
+static const char *spi_acpi_name(struct device *dev)
+{
+ struct drivers_spi_acpi_config *config = dev->chip_info;
+ static char name[5];
+
+ if (config->name)
+ return config->name;
+
+ snprintf(name, sizeof(name), "S%03.3X", spi_acpi_get_bus(dev));
+ name[4] = '\0';
+ return name;
+}
+
+static struct device_operations spi_acpi_ops = {
+ .read_resources = DEVICE_NOOP,
+ .set_resources = DEVICE_NOOP,
+ .enable_resources = DEVICE_NOOP,
+ .acpi_name = &spi_acpi_name,
+ .acpi_fill_ssdt_generator = &spi_acpi_fill_ssdt_generator,
+};
+
+static void spi_acpi_enable(struct device *dev)
+{
+ dev->ops = &spi_acpi_ops;
+}
+
+struct chip_operations drivers_spi_acpi_ops = {
+ CHIP_NAME("SPI Device")
+ .enable_dev = &spi_acpi_enable
+};
diff --git a/src/drivers/spi/acpi/chip.h b/src/drivers/spi/acpi/chip.h
new file mode 100644
index 0000000..4e7f8e7
--- /dev/null
+++ b/src/drivers/spi/acpi/chip.h
@@ -0,0 +1,32 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2017 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 __SPI_ACPI_CHIP_H__
+#define __SPI_ACPI_CHIP_H__
+
+#include <arch/acpi_device.h>
+
+struct drivers_spi_acpi_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 */
+ unsigned speed; /* Bus speed in Hz(required) */
+ const char *compat_string; /* Compatible string for _HID=PRP0001 */
+ struct acpi_irq irq; /* Interrupt */
+};
+
+#endif /* __SPI_ACPI_CHIP_H__ */
Furquan Shaikh (furquan(a)google.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/18340
-gerrit
commit 17f51797af8bc7e71dd4cdeb766d59d1397ab44c
Author: Furquan Shaikh <furquan(a)chromium.org>
Date: Sat Feb 11 10:57:23 2017 -0800
device: Add a new "SPI" device type
Add support for a new "SPI" device type in the devicetree to bind a
device on the SPI bus. Allow device to provide chip select number for
the device as a parameter.
Add spi_bus_operations with operation dev_to_bus which allows SoCs to
define a translation method for converting "struct device" into a unique
SPI bus number.
BUG=chrome-os-partner:59832
BRANCH=None
TEST=Compiles successfully.
Change-Id: I86f09516d3cddd619fef23a4659c9e4eadbcf3fa
Signed-off-by: Furquan Shaikh <furquan(a)chromium.org>
---
src/device/device_util.c | 10 ++++++++++
src/include/device/device.h | 2 ++
src/include/device/path.h | 10 +++++++++-
src/include/device/spi.h | 30 ++++++++++++++++++++++++++++++
4 files changed, 51 insertions(+), 1 deletion(-)
diff --git a/src/device/device_util.c b/src/device/device_util.c
index 1a0a60f..e31ade5 100644
--- a/src/device/device_util.c
+++ b/src/device/device_util.c
@@ -250,6 +250,9 @@ u32 dev_path_encode(device_t dev)
case DEVICE_PATH_GENERIC:
ret |= dev->path.generic.subid << 8 | dev->path.generic.id;
break;
+ case DEVICE_PATH_SPI:
+ ret |= dev->path.spi.cs;
+ break;
case DEVICE_PATH_NONE:
default:
break;
@@ -319,6 +322,10 @@ const char *dev_path(device_t dev)
"GENERIC: %d.%d", dev->path.generic.id,
dev->path.generic.subid);
break;
+ case DEVICE_PATH_SPI:
+ snprintf(buffer, sizeof (buffer), "SPI: %02x",
+ dev->path.spi.cs);
+ break;
default:
printk(BIOS_ERR, "Unknown device path type: %d\n",
dev->path.type);
@@ -390,6 +397,9 @@ int path_eq(struct device_path *path1, struct device_path *path2)
equal = (path1->generic.id == path2->generic.id) &&
(path1->generic.subid == path2->generic.subid);
break;
+ case DEVICE_PATH_SPI:
+ equal = (path1->spi.cs == path2->spi.cs);
+ break;
default:
printk(BIOS_ERR, "Unknown device type: %d\n", path1->type);
break;
diff --git a/src/include/device/device.h b/src/include/device/device.h
index 47509f7..e21384b 100644
--- a/src/include/device/device.h
+++ b/src/include/device/device.h
@@ -23,6 +23,7 @@ struct pci_bus_operations;
struct i2c_bus_operations;
struct smbus_bus_operations;
struct pnp_mode_ops;
+struct spi_bus_operations;
/* Chip operations */
struct chip_operations {
@@ -64,6 +65,7 @@ struct device_operations {
#endif
const struct pci_operations *ops_pci;
const struct i2c_bus_operations *ops_i2c_bus;
+ const struct spi_bus_operations *ops_spi_bus;
const struct smbus_bus_operations *ops_smbus_bus;
const struct pci_bus_operations * (*ops_pci_bus)(device_t dev);
const struct pnp_mode_ops *ops_pnp_mode;
diff --git a/src/include/device/path.h b/src/include/device/path.h
index 9d7fb38..b600272 100644
--- a/src/include/device/path.h
+++ b/src/include/device/path.h
@@ -14,6 +14,7 @@ enum device_path_type {
DEVICE_PATH_CPU_BUS,
DEVICE_PATH_IOAPIC,
DEVICE_PATH_GENERIC,
+ DEVICE_PATH_SPI,
/*
* When adding path types to this table, please also update the
@@ -33,7 +34,8 @@ enum device_path_type {
"DEVICE_PATH_CPU", \
"DEVICE_PATH_CPU_BUS", \
"DEVICE_PATH_IOAPIC", \
- "DEVICE_PATH_GENERIC" \
+ "DEVICE_PATH_GENERIC", \
+ "DEVICE_PATH_SPI", \
}
struct domain_path
@@ -58,6 +60,11 @@ struct i2c_path
unsigned mode_10bit;
};
+struct spi_path
+{
+ unsigned cs;
+};
+
struct apic_path
{
unsigned apic_id;
@@ -107,6 +114,7 @@ struct device_path {
struct cpu_path cpu;
struct cpu_bus_path cpu_bus;
struct generic_path generic;
+ struct spi_path spi;
};
};
diff --git a/src/include/device/spi.h b/src/include/device/spi.h
new file mode 100644
index 0000000..4315ebc
--- /dev/null
+++ b/src/include/device/spi.h
@@ -0,0 +1,30 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2017 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 __DEVICE_SPI_H__
+#define __DEVICE_SPI_H__
+
+struct device;
+struct spi_bus_operations {
+ /*
+ * This is a SoC-specific method that can be provided to translate the
+ * 'struct device' for a SPI controller into a unique SPI bus
+ * number. Returns -1 if the bus number for this bus cannot be
+ * determined.
+ */
+ int (*dev_to_bus)(struct device *dev);
+};
+
+#endif /* __DEVICE_SPI_H__ */
YH Lin (yueherngl(a)chromium.org) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/18324
-gerrit
commit 1380151d62e481c1c2587bc9e4cc2b0c16c1e378
Author: YH Lin <yueherngl(a)google.com>
Date: Fri Feb 10 08:33:01 2017 -0800
mainboard/google/reef: add sand variant
Create the initial Sand variant which refers to the Reef.
Sand is APL board that derives from reference board Reef.
BRANCH=master
BUG=chrome-os-partner:62200
TEST=Build (as initial setup)
Signed-off-by: YH Lin <yueherngl(a)chromium.org>
Change-Id: Iba8c5653b6176676c759d2b48063f0c0c6cde625
---
src/mainboard/google/reef/Kconfig | 3 +++
src/mainboard/google/reef/Kconfig.name | 5 +++++
.../reef/variants/sand/include/variant/acpi/dptf.asl | 18 ++++++++++++++++++
.../google/reef/variants/sand/include/variant/ec.h | 17 +++++++++++++++++
.../google/reef/variants/sand/include/variant/gpio.h | 17 +++++++++++++++++
5 files changed, 60 insertions(+)
diff --git a/src/mainboard/google/reef/Kconfig b/src/mainboard/google/reef/Kconfig
index f37b7b4..856dd84 100644
--- a/src/mainboard/google/reef/Kconfig
+++ b/src/mainboard/google/reef/Kconfig
@@ -64,6 +64,7 @@ config VARIANT_DIR
string
default "reef" if BOARD_GOOGLE_REEF
default "pyro" if BOARD_GOOGLE_PYRO
+ default "sand" if BOARD_GOOGLE_SAND
default "snappy" if BOARD_GOOGLE_SNAPPY
config DEVICETREE
@@ -76,6 +77,7 @@ config MAINBOARD_PART_NUMBER
string
default "Reef" if BOARD_GOOGLE_REEF
default "Pyro" if BOARD_GOOGLE_PYRO
+ default "Sand" if BOARD_GOOGLE_SAND
default "Snappy" if BOARD_GOOGLE_SNAPPY
config MAINBOARD_FAMILY
@@ -87,6 +89,7 @@ config GBB_HWID
depends on CHROMEOS
default "REEF TEST 3240" if BOARD_GOOGLE_REEF
default "PYRO TEST 0290" if BOARD_GOOGLE_PYRO
+ default "SAND TEST 1904" if BOARD_GOOGLE_SAND
default "SNAPPY TEST 1088" if BOARD_GOOGLE_SNAPPY
config MAX_CPUS
diff --git a/src/mainboard/google/reef/Kconfig.name b/src/mainboard/google/reef/Kconfig.name
index 63e6ada..95e3e55 100644
--- a/src/mainboard/google/reef/Kconfig.name
+++ b/src/mainboard/google/reef/Kconfig.name
@@ -8,6 +8,11 @@ config BOARD_GOOGLE_PYRO
select BOARD_GOOGLE_BASEBOARD_REEF
select BASEBOARD_REEF_LAPTOP
+config BOARD_GOOGLE_SAND
+ bool "Sand"
+ select BOARD_GOOGLE_BASEBOARD_REEF
+ select BASEBOARD_REEF_LAPTOP
+
config BOARD_GOOGLE_SNAPPY
bool "Snappy"
select BOARD_GOOGLE_BASEBOARD_REEF
diff --git a/src/mainboard/google/reef/variants/sand/include/variant/acpi/dptf.asl b/src/mainboard/google/reef/variants/sand/include/variant/acpi/dptf.asl
new file mode 100644
index 0000000..fe4bf01
--- /dev/null
+++ b/src/mainboard/google/reef/variants/sand/include/variant/acpi/dptf.asl
@@ -0,0 +1,18 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015 Intel Corporation.
+ *
+ * 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.
+ */
+
+/* Use the one from baseboard for now until the real testing is done. */
+#include <baseboard/acpi/dptf.asl>
diff --git a/src/mainboard/google/reef/variants/sand/include/variant/ec.h b/src/mainboard/google/reef/variants/sand/include/variant/ec.h
new file mode 100644
index 0000000..94424e1
--- /dev/null
+++ b/src/mainboard/google/reef/variants/sand/include/variant/ec.h
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+
+/* Use the one from baseboard for now */
+#include <baseboard/ec.h>
diff --git a/src/mainboard/google/reef/variants/sand/include/variant/gpio.h b/src/mainboard/google/reef/variants/sand/include/variant/gpio.h
new file mode 100644
index 0000000..5eeeec9
--- /dev/null
+++ b/src/mainboard/google/reef/variants/sand/include/variant/gpio.h
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+
+/* Use the one from baseboard for now */
+#include <baseboard/gpio.h>
Mathias Krause (minipli(a)googlemail.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/18336
-gerrit
commit 12ad262ee22173fc32de216909af9192b29ddf8c
Author: Mathias Krause <minipli(a)googlemail.com>
Date: Sat Feb 11 22:47:04 2017 +0100
libpayload: x86/head - implement argc/argv handling
Implement the argc/argv passing as described in [1].
While at it, give the code some love by not needlessly trashing register
values.
[1] http://www.coreboot.org/Payload_API
Change-Id: Ib830f2c67b631b7216843203cefd55d9bb780d83
Signed-off-by: Mathias Krause <minipli(a)googlemail.com>
---
payloads/libpayload/arch/x86/head.S | 43 +++++++++++++++++++++----------------
1 file changed, 25 insertions(+), 18 deletions(-)
diff --git a/payloads/libpayload/arch/x86/head.S b/payloads/libpayload/arch/x86/head.S
index fa9bb73..37798f3 100644
--- a/payloads/libpayload/arch/x86/head.S
+++ b/payloads/libpayload/arch/x86/head.S
@@ -28,7 +28,7 @@
*/
.code32
- .global _entry, _leave
+ .global _entry
.text
.align 4
@@ -55,6 +55,11 @@ mb_header:
.long _end
.long _init
+#define CB_MAGIC_VALUE 0x12345678
+#define CB_MAGIC 0x04
+#define CB_ARGV 0x08
+#define CB_ARGC 0x10
+
/*
* This function saves off the previous stack and switches us to our
* own execution environment.
@@ -63,34 +68,36 @@ _init:
/* No interrupts, please. */
cli
- /* There is a bunch of stuff missing here to take arguments on the stack
- * See http://www.coreboot.org/Payload_API and exec.S.
- */
- /* Store current stack pointer. */
- movl %esp, %esi
-
/* Store EAX and EBX */
- movl %eax,loader_eax
- movl %ebx,loader_ebx
+ movl %eax, loader_eax
+ movl %ebx, loader_ebx
- /* Setup new stack. */
- movl $_stack, %ebx
+ movl CB_MAGIC(%esp), %eax
+ movl %eax, magic
- movl %ebx, %esp
+ /* Copy argv[] and argc as demanded by the Payload API,
+ * see http://www.coreboot.org/Payload_API and exec.S.
+ */
+ cmpl $CB_MAGIC_VALUE, CB_MAGIC(%esp)
+ jne 1f
+
+ movl CB_ARGV(%esp), %eax
+ movl %eax, main_argv
- /* Save old stack pointer. */
- pushl %esi
+ movl CB_ARGC(%esp), %eax
+ movl %eax, main_argc
+1:
+ /* Store current stack pointer and set up new stack. */
+ movl %esp, _stack
+ movl $(_stack - 4), %esp
/* Let's rock. */
call start_main
/* %eax has the return value - pass it on unmolested */
_leave:
- /* Get old stack pointer. */
- popl %ebx
-
/* Restore old stack. */
- movl %ebx, %esp
+ movl 4(%esp), %esp
/* Return to the original context. */
ret
Mathias Krause (minipli(a)googlemail.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/18335
-gerrit
commit f3a830d9ff05c1220707a08ae83b0bf574016e48
Author: Mathias Krause <minipli(a)googlemail.com>
Date: Sat Feb 11 21:02:08 2017 +0100
libpayload: x86/exec - simplify and robustify the code
Simplify the code by directly using the arguments on the stack as base
pointer relative memory references, instead of loading them into
intermediate registers first.
Make it more robust by preserving all callee safed registers mandated by
the C calling convention (and only those), namely EBP, EBX, ESI and EDI.
Don't assume anything about the register state when the called function
returns -- beside the segment registers and the stack pointer to be
still the same as before the call.
Change-Id: I383d6ccefc5b3d5cca37a1c9b638c231bbc48aa8
Signed-off-by: Mathias Krause <minipli(a)googlemail.com>
---
payloads/libpayload/arch/x86/exec.S | 59 +++++++++++++------------------------
1 file changed, 20 insertions(+), 39 deletions(-)
diff --git a/payloads/libpayload/arch/x86/exec.S b/payloads/libpayload/arch/x86/exec.S
index 54c83f6..f5cb0e3 100644
--- a/payloads/libpayload/arch/x86/exec.S
+++ b/payloads/libpayload/arch/x86/exec.S
@@ -37,67 +37,48 @@
.text
.global i386_do_exec
- .type i386_do_exec,@function
+ .type i386_do_exec,@function
i386_do_exec:
pushl %ebp
movl %esp, %ebp
- pushl %eax
-
- /* Put the run address in %eax */
- movl 8(%ebp), %eax
-
- /* Save off the rest of the registers */
+ /* Save the remaining callee preserved registers */
+ pushl %ebx
pushl %esi
- pushl %ecx
- pushl %ebp
+ pushl %edi
/* Push argc and argv on to the stack.
*
* We need to put a dummy value inbetween, as argc should be at offset
* 0x10, according to the payload API.
*/
-
- movl 12(%ebp), %esi
- movl 16(%ebp), %ecx
-
- pushl %esi
+ pushl 12(%ebp)
pushl $0
- pushl %ecx
+ pushl 16(%ebp)
- /* Move a "magic" number on the stack - the other
- * payload will use this as a clue that the argc
- * and argv are sane
+ /* Push a "magic" number on the stack - the other payload will use this
+ * as a clue that the argc and argv values on the stack are sane.
*/
-
- movl $0x12345678, %ecx
- pushl %ecx
+ pushl $0x12345678
/* Jump to the code */
- call *%eax
-
+ call *8(%ebp)
/* %eax has the return value */
- /* Skip over the argc/argv stuff still on the stack */
- addl $12, %esp
+ /* Skip over the argc/argv stuff still on the stack.
+ * Don't assume %ebp is sane, here. Restore it from the stack.
+ */
+ addl $0x10, %esp
- /* Get back %ebp */
+ /* Restore the saved registers */
+ popl %edi
+ popl %esi
+ popl %ebx
popl %ebp
- /* Get the pointer to the return value
- * and save the return value in it
- */
-
- movl 20(%ebp), %ecx
+ /* Get pointer to return value and save the return value in it. */
+ movl 16(%esp), %ecx
movl %eax, (%ecx)
- /* Get the rest of the saved registers */
- popl %ecx
- popl %esi
- popl %eax
-
- /* Restore the stack pointer */
- movl %ebp,%esp
- popl %ebp
ret
Mathias Krause (minipli(a)googlemail.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/18334
-gerrit
commit 6fb883b80dec690669cd45f0601a92a888d102d4
Author: Mathias Krause <minipli(a)googlemail.com>
Date: Tue Feb 7 19:03:29 2017 +0100
libpayload: x86/main - propagate return value of main()
According to [1], the called payload should be able to return a value
via %eax. Support this by changing the prototype of start_main() and
pass on the return value of main() to the caller instead of discarding
it.
[1] https://www.coreboot.org/Payload_API
Change-Id: I8442faea19cc8e04487092f8e61aa4e5cba3ba76
Signed-off-by: Mathias Krause <minipli(a)googlemail.com>
---
payloads/libpayload/arch/x86/main.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/payloads/libpayload/arch/x86/main.c b/payloads/libpayload/arch/x86/main.c
index fbd4dc4..f9a5e2c 100644
--- a/payloads/libpayload/arch/x86/main.c
+++ b/payloads/libpayload/arch/x86/main.c
@@ -42,8 +42,8 @@ char *main_argv[MAX_ARGC_COUNT];
* This is our C entry function - set up the system
* and jump into the payload entry point.
*/
-void start_main(void);
-void start_main(void)
+int start_main(void);
+int start_main(void)
{
extern int main(int argc, char **argv);
@@ -67,10 +67,9 @@ void start_main(void)
* In the future we may care about the return value.
*/
- (void) main(main_argc, (main_argc != 0) ? main_argv : NULL);
-
/*
- * Returning here will go to the _leave function to return
+ * Returning from main() will go to the _leave function to return
* us to the original context.
*/
+ return main(main_argc, (main_argc != 0) ? main_argv : NULL);
}