[coreboot] Patch set updated for coreboot: 866b519 Make the device tree available in the rom stage

Stefan Reinauer (stefan.reinauer@coreboot.org) gerrit at coreboot.org
Fri Aug 3 23:09:08 CEST 2012


Stefan Reinauer (stefan.reinauer at coreboot.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/1398

-gerrit

commit 866b519aa88a4177508d182b4c18a61b919d94c5
Author: Stefan Reinauer <reinauer at chromium.org>
Date:   Tue Jul 31 16:47:25 2012 -0700

    Make the device tree available in the rom stage
    
    We thought about two ways to do this change. The way we decided to try
    was to
    1. drop all ops from devices in romstage
    2. constify all devices in romstage (make them read-only) so we can
       compile static.c into romstage
    3. the device tree "devices" can be used to read configuration from
       the device tree (and nothing else, really)
    4. the device tree devices are accessed through struct device * in
       romstage only. device_t stays the typedef to int in romstage
    5. Use the same static.c file in ramstage and romstage
    
    We declare structs as follows:
    ROMSTAGE_CONST struct bus dev_root_links[];
    ROMSTAGE_CONST is const in romstage and empty in ramstage; This
    forces all of the device tree into the text area.
    
    So a struct looks like this:
    static ROMSTAGE_CONST struct device _dev21 = {
     #ifndef __PRE_RAM__
            .ops = 0,
     #endif
            .bus = &_dev7_links[0],
            .path = {.type=DEVICE_PATH_PCI,{.pci={ .devfn = PCI_DEVFN(0x1c,3)}}},
            .enabled = 0,
            .on_mainboard = 1,
            .subsystem_vendor = 0x1ae0,
            .subsystem_device = 0xc000,
            .link_list = NULL,
            .sibling = &_dev22,
     #ifndef __PRE_RAM__
            .chip_ops = &southbridge_intel_bd82x6x_ops,
     #endif
            .chip_info = &southbridge_intel_bd82x6x_info_10,
            .next=&_dev22
    };
    
    Change-Id: I722454d8d3c40baf7df989f5a6891f6ba7db5727
    Signed-off-by: Ronald G. Minnich <rminnich at chromium.org>
    Signed-off-by: Stefan Reinauer <reinauer at google.com>
---
 Makefile.inc                                 |    5 ++
 src/arch/x86/include/stddef.h                |    6 ++
 src/cpu/amd/agesa/s3_resume.c                |    2 +
 src/devices/Makefile.inc                     |    2 +
 src/devices/device_romstage.c                |   80 ++++++++++++++++++++++++++
 src/include/device/device.h                  |   35 +++++++----
 src/include/device/pci.h                     |    3 +
 src/include/device/resource.h                |    3 +-
 util/lint/lint-stable-002-build-dir-handling |   17 ++++--
 util/sconfig/main.c                          |   32 +++++++----
 10 files changed, 154 insertions(+), 31 deletions(-)

diff --git a/Makefile.inc b/Makefile.inc
index ca1e066..083d423 100644
--- a/Makefile.inc
+++ b/Makefile.inc
@@ -228,6 +228,7 @@ $(obj)/mainboard/$(MAINBOARDDIR)/static.c: $(src)/mainboard/$(MAINBOARDDIR)/devi
 	$(objutil)/sconfig/sconfig $(MAINBOARDDIR) $(obj)/mainboard/$(MAINBOARDDIR)
 
 ramstage-y+=$(obj)/mainboard/$(MAINBOARDDIR)/static.c
+romstage-y+=$(obj)/mainboard/$(MAINBOARDDIR)/static.c
 
 $(objutil)/%.o: $(objutil)/%.c
 	@printf "    HOSTCC     $(subst $(objutil)/,,$(@))\n"
@@ -237,6 +238,10 @@ $(obj)/%.ramstage.o $(abspath $(obj))/%.ramstage.o: $(obj)/%.c $(obj)/config.h $
 	@printf "    CC         $(subst $(obj)/,,$(@))\n"
 	$(CC) -MMD $(CFLAGS) -c -o $@ $<
 
+$(obj)/%.romstage.o $(abspath $(obj))/%.romstage.o: $(obj)/%.c $(obj)/config.h $(OPTION_TABLE_H)
+	@printf "    CC         $(subst $(obj)/,,$(@))\n"
+	$(CC) -MMD -D__PRE_RAM__ $(CFLAGS) -c -o $@ $<
+
 #######################################################################
 # Clean up rules
 clean-abuild:
diff --git a/src/arch/x86/include/stddef.h b/src/arch/x86/include/stddef.h
index a6c3fc6..fc89de5 100644
--- a/src/arch/x86/include/stddef.h
+++ b/src/arch/x86/include/stddef.h
@@ -15,4 +15,10 @@ typedef unsigned int wint_t;
 
 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
 
+#ifdef __PRE_RAM__
+#define ROMSTAGE_CONST const
+#else
+#define ROMSTAGE_CONST
+#endif
+
 #endif /* I386_STDDEF_H */
diff --git a/src/cpu/amd/agesa/s3_resume.c b/src/cpu/amd/agesa/s3_resume.c
index 6bb053d..0348a9f 100644
--- a/src/cpu/amd/agesa/s3_resume.c
+++ b/src/cpu/amd/agesa/s3_resume.c
@@ -29,7 +29,9 @@
 #endif
 #include <device/device.h>
 #include <device/pci.h>
+#ifndef __PRE_RAM__
 #include <device/pci_ops.h>
+#endif
 #include <arch/io.h>
 #include <arch/acpi.h>
 #include <string.h>
diff --git a/src/devices/Makefile.inc b/src/devices/Makefile.inc
index 9ffc0bb..9a2f71e 100644
--- a/src/devices/Makefile.inc
+++ b/src/devices/Makefile.inc
@@ -11,6 +11,8 @@ ramstage-y += pnp_device.c
 ramstage-y += pci_ops.c
 ramstage-y += smbus_ops.c
 
+romstage-y+= device_romstage.c
+
 subdirs-y += oprom
 
 ifeq ($(CONFIG_PCI_ROM_RUN),y)
diff --git a/src/devices/device_romstage.c b/src/devices/device_romstage.c
new file mode 100644
index 0000000..475f94a
--- /dev/null
+++ b/src/devices/device_romstage.c
@@ -0,0 +1,80 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2003-2004 Linux Networx
+ * (Written by Eric Biederman <ebiederman at lnxi.com> for Linux Networx)
+ * Copyright (C) 2003 Greg Watson <jarrah at users.sourceforge.net>
+ * Copyright (C) 2004 Li-Ta Lo <ollie at lanl.gov>
+ * Copyright (C) 2005-2006 Tyan
+ * (Written by Yinghai Lu <yhlu at tyan.com> for Tyan)
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <device/device.h>
+#include <device/path.h>
+#include <device/pci.h>
+#include <device/resource.h>
+
+/** Linked list of ALL devices */
+ROMSTAGE_CONST struct device * ROMSTAGE_CONST all_devices = &dev_root;
+
+/**
+ * Given a PCI bus and a devfn number, find the device structure.
+ *
+ * @param bus The bus number.
+ * @param devfn A device/function number.
+ * @return Pointer to the device structure (if found), 0 otherwise.
+ */
+ROMSTAGE_CONST struct device *dev_find_slot(unsigned int bus,
+						unsigned int devfn)
+{
+	ROMSTAGE_CONST struct device *dev, *result;
+
+	result = 0;
+	for (dev = all_devices; dev; dev = dev->next) {
+		if ((dev->path.type == DEVICE_PATH_PCI) &&
+		    (dev->bus->secondary == bus) &&
+		    (dev->path.pci.devfn == devfn)) {
+			result = dev;
+			break;
+		}
+	}
+	return result;
+}
+
+/**
+ * Given an SMBus bus and a device number, find the device structure.
+ *
+ * @param bus The bus number.
+ * @param addr A device number.
+ * @return Pointer to the device structure (if found), 0 otherwise.
+ */
+ROMSTAGE_CONST struct device *dev_find_slot_on_smbus(unsigned int bus,
+							unsigned int addr)
+{
+	ROMSTAGE_CONST struct device *dev, *result;
+
+	result = 0;
+	for (dev = all_devices; dev; dev = dev->next) {
+		if ((dev->path.type == DEVICE_PATH_I2C) &&
+		    (dev->bus->secondary == bus) &&
+		    (dev->path.i2c.device == addr)) {
+			result = dev;
+			break;
+		}
+	}
+	return result;
+}
+
diff --git a/src/include/device/device.h b/src/include/device/device.h
index 0b15ac5..b44a551 100644
--- a/src/include/device/device.h
+++ b/src/include/device/device.h
@@ -2,11 +2,12 @@
 #define DEVICE_H
 
 #include <stdint.h>
+#include <stddef.h>
 #include <device/resource.h>
 #include <device/path.h>
 
-
 struct device;
+#ifndef __PRE_RAM__
 typedef struct device * device_t;
 struct pci_operations;
 struct pci_bus_operations;
@@ -42,12 +43,14 @@ struct device_operations {
 	const struct smbus_bus_operations *ops_smbus_bus;
 	const struct pci_bus_operations *ops_pci_bus;
 };
+#endif
 
 
 struct bus {
-	device_t 	dev;		/* This bridge device */
-	device_t 	children;	/* devices behind this bridge */
-	struct bus	*next;		/* The next bridge on this device */
+
+	ROMSTAGE_CONST struct device * 	dev;		/* This bridge device */
+	ROMSTAGE_CONST struct device * 	children;	/* devices behind this bridge */
+	ROMSTAGE_CONST struct bus	*next;		/* The next bridge on this device */
 	unsigned	bridge_ctrl;	/* Bridge control register */
 	unsigned char	link_num;	/* The index of this link */
 	uint16_t	secondary; 	/* secondary bus number */
@@ -70,10 +73,12 @@ struct pci_irq_info {
 };
 
 struct device {
-	struct bus *	bus;		/* bus this device is on, for bridge
+	ROMSTAGE_CONST struct bus *	bus;		/* bus this device is on, for bridge
 					 * devices, it is the up stream bus */
-	device_t	sibling;	/* next device on this bus */
-	device_t	next;		/* chain of all devices */
+
+	ROMSTAGE_CONST struct device *	sibling;	/* next device on this bus */
+
+	ROMSTAGE_CONST struct device *	next;		/* chain of all devices */
 
 	struct device_path path;
 	unsigned 	vendor;
@@ -89,23 +94,24 @@ struct device {
 	u8 command;
 
 	/* Base registers for this device. I/O, MEM and Expansion ROM */
-	struct resource *resource_list;
+	ROMSTAGE_CONST struct resource *resource_list;
 
 	/* links are (downstream) buses attached to the device, usually a leaf
 	 * device with no children has 0 buses attached and a bridge has 1 bus
 	 */
-	struct bus *link_list;
+	ROMSTAGE_CONST struct bus *link_list;
 
 	struct device_operations *ops;
 	const struct chip_operations *chip_ops;
-	void *chip_info;
+	ROMSTAGE_CONST void *chip_info;
 };
 
 /**
  * This is the root of the device tree. The device tree is defined in the
  * static.c file and is generated by the config tool at compile time.
  */
-extern struct device	dev_root;
+extern ROMSTAGE_CONST struct device	dev_root;
+#ifndef __PRE_RAM__
 extern struct device	*all_devices;	/* list of all devices */
 
 extern struct resource	*free_resources;
@@ -195,5 +201,10 @@ void fixed_mem_resource(device_t dev, unsigned long index,
 
 void tolm_test(void *gp, struct device *dev, struct resource *new);
 u32 find_pci_tolm(struct bus *bus);
-
+#else
+ROMSTAGE_CONST struct device * dev_find_slot (unsigned int bus,
+						unsigned int devfn);
+ROMSTAGE_CONST struct device * dev_find_slot_on_smbus (unsigned int bus,
+							unsigned int addr);
+#endif
 #endif /* DEVICE_H */
diff --git a/src/include/device/pci.h b/src/include/device/pci.h
index 51d5283..a215a2a 100644
--- a/src/include/device/pci.h
+++ b/src/include/device/pci.h
@@ -16,9 +16,11 @@
 #define PCI_H
 
 #include <stdint.h>
+#include <stddef.h>
 #include <device/pci_def.h>
 #include <device/resource.h>
 #include <device/device.h>
+#ifndef __PRE_RAM__
 #include <device/pci_ops.h>
 #include <device/pci_rom.h>
 
@@ -107,4 +109,5 @@ static inline const struct pci_bus_operations *ops_pci_bus(struct bus *bus)
 unsigned mainboard_pci_subsystem_vendor_id(struct device *dev);
 unsigned mainboard_pci_subsystem_device_id(struct device *dev);
 
+#endif
 #endif /* PCI_H */
diff --git a/src/include/device/resource.h b/src/include/device/resource.h
index c28ada5..ddedc2f 100644
--- a/src/include/device/resource.h
+++ b/src/include/device/resource.h
@@ -2,6 +2,7 @@
 #define DEVICE_RESOURCE_H
 
 #include <stdint.h>
+#include <stddef.h>
 
 #define IORESOURCE_BITS		0x000000ff	/* Bus-specific bits */
 
@@ -72,7 +73,7 @@ struct resource {
 	resource_t base;	/* Base address of the resource */
 	resource_t size;	/* Size of the resource */
 	resource_t limit;	/* Largest valid value base + size -1 */
-	struct resource* next;	/* Next resource in the list */
+	ROMSTAGE_CONST struct resource* next;	/* Next resource in the list */
 	unsigned long flags;	/* Descriptions of the kind of resource */
 	unsigned long index;	/* Bus specific per device resource id */
 	unsigned char align;	/* Required alignment (log 2) of the resource */
diff --git a/util/lint/lint-stable-002-build-dir-handling b/util/lint/lint-stable-002-build-dir-handling
index c4247b5..d5295d2 100755
--- a/util/lint/lint-stable-002-build-dir-handling
+++ b/util/lint/lint-stable-002-build-dir-handling
@@ -20,7 +20,7 @@
 
 # $1: command to test for GNU make
 search_make() {
-if [ -n "`$1 --version 2>&1 |grep GNU`" ]; then MAKE=$1; fi
+if [ -n "`$1 --version 2>&1 | grep GNU`" ]; then MAKE=$1; fi
 }
 
 # if $1 and $2 differ, exit with failure
@@ -33,7 +33,12 @@ fi
 
 # $1: object directory
 run_printall() {
-$MAKE CONFIG_USE_BLOBS=n CONFIG_CCACHE=n CONFIG_SCANBUILD_ENABLE=n NOMKDIR=1 DOTCONFIG=$TMPCONFIG obj=$1 printall |sed -e "s,^ *,," -e "s,^ramstage-objs:=,," -e "s,mainboard/[^/]*/[^/]*/,.../," |tr " " "\n"|grep "/static.*\.[co]" |sort |tr '\012\015' '  ' |sed -e "s,  *, ,g" -e "s, *$,,"
+$MAKE CONFIG_USE_BLOBS=n CONFIG_CCACHE=n CONFIG_SCANBUILD_ENABLE=n NOMKDIR=1 \
+	DOTCONFIG=$TMPCONFIG obj=$1 printall |        \
+	sed -e "s,^ *,," -e "s,^r.mstage-objs:=,,"    \
+	    -e "s,mainboard/[^/]*/[^/]*/,.../,g" |    \
+	tr " " "\n" | grep "/static.*\.[co]" | sort | \
+	tr '\012\015' '  ' | sed -e "s,  *, ,g" -e "s, *$,,"
 }
 
 # find GNU make
@@ -54,10 +59,10 @@ $MAKE DOTCONFIG=$TMPCONFIG allyesconfig >/dev/null
 # look up parent directory
 PARENTDIR=`dirname $PWD`
 
-compare_output "`run_printall build`" "build/.../static.c build/.../static.ramstage.o"
-compare_output "`run_printall ../obj`" "$PARENTDIR/obj/.../static.c $PARENTDIR/obj/.../static.ramstage.o"
-compare_output "`run_printall /tmp`" "/tmp/.../static.c /tmp/.../static.ramstage.o"
-compare_output "`run_printall /../tmp`" "/tmp/.../static.c /tmp/.../static.ramstage.o"
+compare_output "`run_printall build`" "build/.../static.c build/.../static.c build/.../static.ramstage.o build/.../static.romstage.o"
+compare_output "`run_printall ../obj`" "$PARENTDIR/obj/.../static.c $PARENTDIR/obj/.../static.c $PARENTDIR/obj/.../static.ramstage.o $PARENTDIR/obj/.../static.romstage.o"
+compare_output "`run_printall /tmp`" "/tmp/.../static.c /tmp/.../static.c /tmp/.../static.ramstage.o /tmp/.../static.romstage.o"
+compare_output "`run_printall /../tmp`" "/tmp/.../static.c /tmp/.../static.c /tmp/.../static.ramstage.o /tmp/.../static.romstage.o"
 
 rm -f $TMPCONFIG
 
diff --git a/util/sconfig/main.c b/util/sconfig/main.c
index 824bc6c..82a7491 100644
--- a/util/sconfig/main.c
+++ b/util/sconfig/main.c
@@ -366,13 +366,15 @@ void add_ioapic_info(struct device *dev, int apicid, const char *_srcpin, int ir
 
 static void pass0(FILE *fil, struct device *ptr) {
 	if (ptr->type == device && ptr->id == 0)
-		fprintf(fil, "struct bus %s_links[];\n", ptr->name);
+		fprintf(fil, "ROMSTAGE_CONST struct bus %s_links[];\n", ptr->name);
+
 	if ((ptr->type == device) && (ptr->id != 0) && (!ptr->used)) {
-		fprintf(fil, "static struct device %s;\n", ptr->name);
+		fprintf(fil, "ROMSTAGE_CONST static struct device %s;\n", ptr->name);
 		if (ptr->rescnt > 0)
-			fprintf(fil, "struct resource %s_res[];\n", ptr->name);
+			fprintf(fil, "ROMSTAGE_CONST struct resource %s_res[];\n", ptr->name);
 		if (ptr->children || ptr->multidev)
-			fprintf(fil, "struct bus %s_links[];\n", ptr->name);
+			fprintf(fil, "ROMSTAGE_CONST struct bus %s_links[];\n",
+					ptr->name);
 	}
 }
 
@@ -382,8 +384,10 @@ static void pass1(FILE *fil, struct device *ptr)
 	if (!ptr->used && (ptr->type == device)) {
 		if (ptr->id != 0)
 			fprintf(fil, "static ");
-		fprintf(fil, "struct device %s = {\n", ptr->name);
+		fprintf(fil, "ROMSTAGE_CONST struct device %s = {\n", ptr->name);
+		fprintf(fil, "#ifndef __PRE_RAM__\n");
 		fprintf(fil, "\t.ops = %s,\n", (ptr->ops)?(ptr->ops):"0");
+		fprintf(fil, "#endif\n");
 		fprintf(fil, "\t.bus = &%s_links[%d],\n", ptr->bus->name, ptr->bus->link);
 		fprintf(fil, "\t.path = {");
 		fprintf(fil, ptr->path, ptr->path_a, ptr->path_b);
@@ -415,7 +419,9 @@ static void pass1(FILE *fil, struct device *ptr)
 		if (ptr->sibling)
 			fprintf(fil, "\t.sibling = &%s,\n", ptr->sibling->name);
 		if (ptr->chip->chiph_exists) {
+			fprintf(fil, "#ifndef __PRE_RAM__\n");
 			fprintf(fil, "\t.chip_ops = &%s_ops,\n", ptr->chip->name_underscore);
+			fprintf(fil, "#endif\n");
 			fprintf(fil, "\t.chip_info = &%s_info_%d,\n", ptr->chip->name_underscore, ptr->chip->id);
 		}
 		if (ptr->nextdev)
@@ -424,7 +430,8 @@ static void pass1(FILE *fil, struct device *ptr)
 	}
 	if (ptr->rescnt > 0) {
 		int i=1;
-		fprintf(fil, "struct resource %s_res[] = {\n", ptr->name);
+		fprintf(fil, "ROMSTAGE_CONST struct resource %s_res[] = {\n",
+				ptr->name);
 		struct resource *r = ptr->res;
 		while (r) {
 			fprintf(fil, "\t\t{ .flags=IORESOURCE_FIXED | IORESOURCE_ASSIGNED | IORESOURCE_");
@@ -441,7 +448,7 @@ static void pass1(FILE *fil, struct device *ptr)
 		fprintf(fil, "\t };\n");
 	}
 	if (!ptr->used && ptr->type == device && (ptr->children || ptr->multidev)) {
-		fprintf(fil, "struct bus %s_links[] = {\n", ptr->name);
+		fprintf(fil, "ROMSTAGE_CONST struct bus %s_links[] = {\n", ptr->name);
 		if (ptr->multidev) {
 			struct device *d = ptr;
 			while (d) {
@@ -473,8 +480,9 @@ static void pass1(FILE *fil, struct device *ptr)
 	}
 	if ((ptr->type == chip) && (ptr->chiph_exists)) {
 		if (ptr->reg) {
-			fprintf(fil, "struct %s_config %s_info_%d\t= {\n",
-				ptr->name_underscore, ptr->name_underscore, ptr->id);
+			fprintf(fil, "ROMSTAGE_CONST struct %s_config ROMSTAGE_CONST %s_info_%d = {\n",
+				ptr->name_underscore, ptr->name_underscore,
+				ptr->id);
 			struct reg *r = ptr->reg;
 			while (r) {
 				fprintf(fil, "\t.%s = %s,\n", r->key, r->value);
@@ -482,7 +490,7 @@ static void pass1(FILE *fil, struct device *ptr)
 			}
 			fprintf(fil, "};\n\n");
 		} else {
-			fprintf(fil, "struct %s_config %s_info_%d;\n",
+			fprintf(fil, "ROMSTAGE_CONST struct %s_config ROMSTAGE_CONST %s_info_%d = { };\n",
 				ptr->name_underscore, ptr->name_underscore, ptr->id);
 		}
 	}
@@ -617,9 +625,9 @@ int main(int argc, char** argv) {
 		fprintf(autogen, "\n/* pass 0 */\n");
 		walk_device_tree(autogen, &root, pass0, NULL);
 		fprintf(autogen, "\n/* pass 1 */\n"
-			    "struct device *last_dev = &%s;\n", lastdev->name);
+			    "ROMSTAGE_CONST struct device * ROMSTAGE_CONST last_dev = &%s;\n", lastdev->name);
 #ifdef MAINBOARDS_HAVE_CHIP_H
-		fprintf(autogen, "struct mainboard_config mainboard_info_0;\n");
+		fprintf(autogen, "static ROMSTAGE_CONST struct mainboard_config ROMSTAGE_CONST mainboard_info_0;\n");
 #endif
 		walk_device_tree(autogen, &root, pass1, NULL);
 




More information about the coreboot mailing list