2010-05-05 13:19:50 +02:00
|
|
|
/*
|
|
|
|
* sconfig, coreboot device tree compiler
|
|
|
|
*
|
|
|
|
* Copyright (C) 2010 coresystems GmbH
|
2016-05-07 10:11:14 +02:00
|
|
|
* written by Patrick Georgi <patrick@georgi-clan.de>
|
2010-05-05 13:19:50 +02:00
|
|
|
*
|
|
|
|
* 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 <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <errno.h>
|
|
|
|
|
|
|
|
struct resource;
|
|
|
|
struct resource {
|
|
|
|
int type;
|
|
|
|
int index;
|
|
|
|
int base;
|
|
|
|
struct resource *next;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct reg;
|
|
|
|
struct reg {
|
|
|
|
char *key;
|
|
|
|
char *value;
|
|
|
|
struct reg *next;
|
|
|
|
};
|
|
|
|
|
2012-06-21 22:19:48 +02:00
|
|
|
struct pci_irq_info {
|
|
|
|
int ioapic_irq_pin;
|
|
|
|
int ioapic_dst_id;
|
|
|
|
};
|
2018-05-31 00:09:09 +02:00
|
|
|
|
2018-05-31 19:33:16 +02:00
|
|
|
struct chip;
|
|
|
|
struct chip_instance {
|
2020-05-03 00:34:42 +02:00
|
|
|
/* Monotonically increasing ID for each chip instance. */
|
2018-05-31 00:09:09 +02:00
|
|
|
int id;
|
|
|
|
|
2018-05-31 19:33:16 +02:00
|
|
|
/* Pointer to registers for this chip. */
|
|
|
|
struct reg *reg;
|
|
|
|
|
|
|
|
/* Pointer to chip of which this is instance. */
|
|
|
|
struct chip *chip;
|
|
|
|
|
|
|
|
/* Pointer to next instance of the same chip. */
|
|
|
|
struct chip_instance *next;
|
2018-06-22 18:19:15 +02:00
|
|
|
|
|
|
|
/*
|
util/sconfig: Drop use of ref_count for chip_instance
chip_instance structure currently uses a ref_count to determine how
many devices hold reference to that instance. If the count drops to
zero, then it is assumed that the chip instance is a duplicate in
override tree and has a similar instance that is already overriden in
base device tree.
ref_count is currently decremented whenever a device in override tree
matches the one in base device tree and the registers from the
override tree instance are copied over to the base tree instance. On
the other hand, if a device in override tree does not match any device
in base tree under a given parent, then the device is added to base
tree and all the devices in its subtree that hold pointers to its
parent chip instance are updated to point to the parent's chip
instance in base tree. This is done as part of update_chip_pointers.
However, there are a couple of issues that this suffers from:
a) If a device is present only in override tree and it does not have
its own chip (i.e. pointing to parent's chip instance), then it
results in sconfig emiiting parent's chip instance (which can be the
SoC chip instance) in static.c even though it is unused. This is
because update_chip_pointers() does not call delete_chip_instance()
before reassigning the chip instance pointer.
b) If a device is added under root device only in the override tree
and it does not have its own chip instance (i.e. uses SoC chip
instance), then it results in sconfig emitting a copy of the SoC chip
instance and setting that as chip_ops for this new device in the
override tree.
In order to fix the above issues, this change drops the ref_count
field from chip_instance structure and instead adds a forwarding
pointer `base_chip_instance`. This is setup as per the following
rules:
1. If the instance belongs to base devicetree, base_chip_instance is
set to NULL.
2. If the instance belongs to override tree, then it is set to its
corresponding chip instance in base tree (if present), else set to
NULL.
State of base_chip_instance is then used when emitting chips and
devices using the following rules:
1. If a chip_instance has non-NULL base_chip_instance, then that chip
instance is not emitted to static.c
2. When emitting chip_ops for a device, base_chip_instance is used to
determine the correct chip instance name to emit.
BUG=b:155549176
TEST=Verified that the static.c file generated for base/override tree
combination is correct when new devices without chips are added only
to override tree.
Change-Id: Idbb5b34f49bf874da3f30ebb6a6a0e2d8d091fe5
Signed-off-by: Furquan Shaikh <furquan@google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/41007
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
2020-05-03 01:05:29 +02:00
|
|
|
* Pointer to corresponding chip instance in base devicetree.
|
|
|
|
* a) If the chip instance belongs to the base devicetree, then this pointer is set to
|
|
|
|
* NULL.
|
|
|
|
* b) If the chip instance belongs to override tree, then this pointer is set to its
|
|
|
|
* corresponding chip instance in base devicetree (if it exists), else to NULL.
|
|
|
|
*
|
|
|
|
* This is useful when generating chip instances and chip_ops for a device to determine
|
|
|
|
* if this is the instance to emit or if there is a base chip instance to use instead.
|
2018-06-22 18:19:15 +02:00
|
|
|
*/
|
util/sconfig: Drop use of ref_count for chip_instance
chip_instance structure currently uses a ref_count to determine how
many devices hold reference to that instance. If the count drops to
zero, then it is assumed that the chip instance is a duplicate in
override tree and has a similar instance that is already overriden in
base device tree.
ref_count is currently decremented whenever a device in override tree
matches the one in base device tree and the registers from the
override tree instance are copied over to the base tree instance. On
the other hand, if a device in override tree does not match any device
in base tree under a given parent, then the device is added to base
tree and all the devices in its subtree that hold pointers to its
parent chip instance are updated to point to the parent's chip
instance in base tree. This is done as part of update_chip_pointers.
However, there are a couple of issues that this suffers from:
a) If a device is present only in override tree and it does not have
its own chip (i.e. pointing to parent's chip instance), then it
results in sconfig emiiting parent's chip instance (which can be the
SoC chip instance) in static.c even though it is unused. This is
because update_chip_pointers() does not call delete_chip_instance()
before reassigning the chip instance pointer.
b) If a device is added under root device only in the override tree
and it does not have its own chip instance (i.e. uses SoC chip
instance), then it results in sconfig emitting a copy of the SoC chip
instance and setting that as chip_ops for this new device in the
override tree.
In order to fix the above issues, this change drops the ref_count
field from chip_instance structure and instead adds a forwarding
pointer `base_chip_instance`. This is setup as per the following
rules:
1. If the instance belongs to base devicetree, base_chip_instance is
set to NULL.
2. If the instance belongs to override tree, then it is set to its
corresponding chip instance in base tree (if present), else set to
NULL.
State of base_chip_instance is then used when emitting chips and
devices using the following rules:
1. If a chip_instance has non-NULL base_chip_instance, then that chip
instance is not emitted to static.c
2. When emitting chip_ops for a device, base_chip_instance is used to
determine the correct chip instance name to emit.
BUG=b:155549176
TEST=Verified that the static.c file generated for base/override tree
combination is correct when new devices without chips are added only
to override tree.
Change-Id: Idbb5b34f49bf874da3f30ebb6a6a0e2d8d091fe5
Signed-off-by: Furquan Shaikh <furquan@google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/41007
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
2020-05-03 01:05:29 +02:00
|
|
|
struct chip_instance *base_chip_instance;
|
2018-05-31 19:33:16 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
struct chip {
|
2018-05-31 00:09:09 +02:00
|
|
|
/* Indicates if chip header exists for this chip. */
|
|
|
|
int chiph_exists;
|
|
|
|
|
|
|
|
/* Name of current chip. */
|
|
|
|
char *name;
|
|
|
|
|
|
|
|
/* Name of current chip normalized to _. */
|
|
|
|
char *name_underscore;
|
|
|
|
|
2018-05-31 19:33:16 +02:00
|
|
|
/* Pointer to first instance of this chip. */
|
|
|
|
struct chip_instance *instance;
|
2018-05-31 00:09:09 +02:00
|
|
|
|
|
|
|
/* Pointer to next chip. */
|
|
|
|
struct chip *next;
|
|
|
|
};
|
|
|
|
|
2010-05-05 13:19:50 +02:00
|
|
|
struct device;
|
2018-06-03 13:22:17 +02:00
|
|
|
struct bus {
|
|
|
|
/* Instance/ID of the bus under the device. */
|
|
|
|
int id;
|
|
|
|
|
|
|
|
/* Pointer to device to which this bus belongs. */
|
|
|
|
struct device *dev;
|
|
|
|
|
|
|
|
/* Pointer to list of children. */
|
|
|
|
struct device *children;
|
|
|
|
|
|
|
|
/* Pointer to next bus for the device. */
|
|
|
|
struct bus *next_bus;
|
|
|
|
};
|
|
|
|
|
2010-05-05 13:19:50 +02:00
|
|
|
struct device {
|
2018-09-10 04:51:26 +02:00
|
|
|
/* Indicates device status (enabled / hidden or not). */
|
2010-05-05 13:19:50 +02:00
|
|
|
int enabled;
|
2018-09-10 04:51:26 +02:00
|
|
|
int hidden;
|
Add configurable ramstage support for minimal PCI scanning
This CL has changes that allow us to enable a configurable
ramstage, and one change that allows us to minimize PCI
scanning. Minimal scanning is a frequently requested feature.
To enable it, we add two new variables to src/Kconfig
CONFIGURABLE_RAMSTAGE
is the overall variable controlling other options for minimizing the
ramstage.
MINIMAL_PCI_SCANNING is how we indicate we wish to enable minimal
PCI scanning.
Some devices must be scanned in all cases, such as 0:0.0.
To indicate which devices we must scan, we add a new mandatory
keyword to sconfig
It is used in place of on, off, or hidden, and indicates
a device is enabled and mandatory. Mandatory
devices are always scanned. When MINIMAL_PCI_SCANNING is enabled,
ONLY mandatory devices are scanned.
We further add support in src/device/pci_device.c to manage
both MINIMAL_PCI_SCANNING and mandatory devices.
Finally, to show how this works in practice, we add mandatory
keywords to 3 devices on the qemu-q35.
TEST=
1. This is tested and working on the qemu-q35 target.
2. On CML-Hatch
Before CL:
Total Boot time: ~685ms
After CL:
Total Boot time: ~615ms
Change-Id: I2073d9f8e9297c2b02530821ebb634ea2a5c758e
Signed-off-by: Ronald G. Minnich <rminnich@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/36221
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Jeremy Soller <jeremy@system76.com>
2019-10-22 04:02:24 +02:00
|
|
|
/* non-zero if the device should be included in all cases */
|
|
|
|
int mandatory;
|
2018-06-03 13:22:17 +02:00
|
|
|
|
|
|
|
/* Subsystem IDs for the device. */
|
2011-03-01 20:58:15 +01:00
|
|
|
int subsystem_vendor;
|
|
|
|
int subsystem_device;
|
|
|
|
int inherit_subsystem;
|
2018-06-03 13:22:17 +02:00
|
|
|
|
|
|
|
/* Name of this device. */
|
2010-05-05 13:19:50 +02:00
|
|
|
char *name;
|
2018-06-03 13:22:17 +02:00
|
|
|
|
|
|
|
/* Path of this device. */
|
2010-05-05 13:19:50 +02:00
|
|
|
char *path;
|
|
|
|
int path_a;
|
|
|
|
int path_b;
|
2018-06-03 13:22:17 +02:00
|
|
|
|
|
|
|
/* Type of bus that exists under this device. */
|
2010-05-05 13:19:50 +02:00
|
|
|
int bustype;
|
2018-06-03 13:22:17 +02:00
|
|
|
|
|
|
|
/* PCI IRQ info. */
|
2012-06-21 22:19:48 +02:00
|
|
|
struct pci_irq_info pci_irq_info[4];
|
2018-05-31 00:09:09 +02:00
|
|
|
|
2018-06-03 13:22:17 +02:00
|
|
|
/* Pointer to bus of parent on which this device resides. */
|
|
|
|
struct bus *parent;
|
|
|
|
|
|
|
|
/* Pointer to next child under the same parent. */
|
2010-05-05 13:19:50 +02:00
|
|
|
struct device *sibling;
|
2018-06-03 13:22:17 +02:00
|
|
|
|
|
|
|
/* Pointer to resources for this device. */
|
2010-05-05 13:19:50 +02:00
|
|
|
struct resource *res;
|
2018-05-31 00:09:09 +02:00
|
|
|
|
2018-06-03 13:22:17 +02:00
|
|
|
/* Pointer to chip instance for this device. */
|
2018-05-31 19:33:16 +02:00
|
|
|
struct chip_instance *chip_instance;
|
2010-05-05 13:19:50 +02:00
|
|
|
|
2018-06-03 13:22:17 +02:00
|
|
|
/* Pointer to list of buses under this device. */
|
|
|
|
struct bus *bus;
|
|
|
|
/* Pointer to last bus under this device. */
|
|
|
|
struct bus *last_bus;
|
2019-04-12 14:42:17 +02:00
|
|
|
|
|
|
|
/* SMBIOS slot type */
|
|
|
|
char *smbios_slot_type;
|
|
|
|
|
|
|
|
/* SMBIOS slot data width */
|
|
|
|
char *smbios_slot_data_width;
|
|
|
|
|
|
|
|
/* SMBIOS slot description for reference designation */
|
|
|
|
char *smbios_slot_designation;
|
|
|
|
|
|
|
|
/* SMBIOS slot length */
|
|
|
|
char *smbios_slot_length;
|
2018-06-03 13:22:17 +02:00
|
|
|
};
|
2010-05-05 13:19:50 +02:00
|
|
|
|
2018-06-03 13:22:17 +02:00
|
|
|
extern struct bus *root_parent;
|
2018-05-31 19:33:16 +02:00
|
|
|
|
2018-06-03 13:22:17 +02:00
|
|
|
struct device *new_device(struct bus *parent,
|
2018-05-31 19:33:16 +02:00
|
|
|
struct chip_instance *chip_instance,
|
2018-05-31 16:52:00 +02:00
|
|
|
const int bustype, const char *devnum,
|
2018-09-10 04:51:26 +02:00
|
|
|
int status);
|
2018-06-03 13:22:17 +02:00
|
|
|
|
|
|
|
void add_resource(struct bus *bus, int type, int index, int base);
|
|
|
|
|
|
|
|
void add_pci_subsystem_ids(struct bus *bus, int vendor, int device,
|
2016-08-06 02:32:18 +02:00
|
|
|
int inherit);
|
2018-06-03 13:22:17 +02:00
|
|
|
|
|
|
|
void add_ioapic_info(struct bus *bus, int apicid, const char *_srcpin,
|
2016-08-06 02:32:18 +02:00
|
|
|
int irqpin);
|
2016-05-07 10:11:14 +02:00
|
|
|
|
2019-04-12 14:42:17 +02:00
|
|
|
void add_slot_desc(struct bus *bus, char *type, char *length, char *designation,
|
|
|
|
char *data_width);
|
|
|
|
|
2016-05-07 10:11:14 +02:00
|
|
|
void yyrestart(FILE *input_file);
|
2018-05-31 00:09:09 +02:00
|
|
|
|
|
|
|
/* Add chip data to tail of queue. */
|
|
|
|
void chip_enqueue_tail(void *data);
|
|
|
|
|
|
|
|
/* Retrieve chip data from tail of queue. */
|
|
|
|
void *chip_dequeue_tail(void);
|
2018-05-31 19:33:16 +02:00
|
|
|
|
|
|
|
struct chip_instance *new_chip_instance(char *path);
|
|
|
|
void add_register(struct chip_instance *chip, char *name, char *val);
|