[PATCH 00/17] RFC: Split configs between U-Boot proper and SPL builds

At present a single .config file is used to configure the build for all phases, with SPL phases having a SPL_ or TPL_ prefix on each CONFIG to indicate which build it controls.
So, for example, we have CONFIG_MISC and CONFIG_SPL_MISC to control the inclusion of MISC drivers in each phase.
From this .config a few other files are generated (by the kconfig tool)
for use with make and from C code (auto.conf and autoconf.h).
This all works well but is a bit ugly in places, for example requiring the use of a SPL_TPL_ macro in Makefiles to distinguish between options intended for SPL and U-Boot proper.
In discussions with trini the idea came up of creating separate config files for each type of build. So instead of using SPL_ or TPL_ prefixes, each build includes its own files with the config it needs.
This series takes a pass at implementing this. It makes only minor changes to the existing Kconfig files, to make things work, but updates the kconfig tool to output seperate files for each phase. These changes may need reworking to send upstream.
With this series, SPL_TPL_ resolves to an empty value, so it is possible to drop this macro.
This cannot be applied as is. Any ad-hoc CONFIG options break the logic in this series, since these are not processed by the kconfig tool. A special xSPL_TPL_ macro is added to show this problem.
A run indicative of the current state (without the last patch, which breaks everything) is here:
https://source.denx.de/u-boot/custodians/u-boot-dm/-/pipelines/9135
Once CONFIG migration is completed, something along these lines can be applied.
Simon Glass (17): env: Avoid checking ENV_IS_IN when env disabled x86: Fix qemu condition for arch_cpu_init() acpi: Add a Kconfig for SPL cmd: Add an SPL Kconfig for CMDLINE and HUSH cros_ec: Add SPL Kconfigs for cros_ec features power: Add SPL Kconfig for sandbox pmc emulator test: Add SPL Kconfig for compression tests sandbox: Enable MISC support for the SPL build serial: Tidy up the Makefile condition for DM_SERIAL virtio: Add SPL Kconfig for virtio kconfig: Refactor code into separate writer functions kconfig: Support writing separate SPL files Makefile: Include the config for the phase being built Makefile: Use empty SPL_ and SPL_TPL_ vars Makefile: Support ad-hoc COMFIX_SPL_IMAGE_SIZE et al kconfig: Update CONFIG_IS_ENABLED() for split files kconfig: Add a new CONFIG() macro
Makefile | 11 +- arch/x86/cpu/qemu/qemu.c | 2 +- cmd/Kconfig | 10 ++ cmd/nvedit.c | 2 + configs/sandbox_noinst_defconfig | 1 + configs/sandbox_spl_defconfig | 1 + drivers/core/Kconfig | 5 + drivers/i2c/Kconfig | 10 ++ drivers/power/acpi_pmc/Kconfig | 5 + drivers/serial/Makefile | 2 +- drivers/virtio/Kconfig | 6 + include/linux/kconfig.h | 91 +++------- scripts/Kbuild.include | 17 +- scripts/Makefile.build | 10 +- scripts/Makefile.spl | 33 +++- scripts/kconfig/conf.c | 4 + scripts/kconfig/confdata.c | 286 ++++++++++++++++++++++++++++--- scripts/kconfig/expr.h | 9 + scripts/kconfig/lkc.h | 9 + test/Kconfig | 5 + 20 files changed, 408 insertions(+), 111 deletions(-)

This check is not needed when the environment is not enabled, e.g. in SPL. Add a condition to handle this.
Signed-off-by: Simon Glass sjg@chromium.org ---
cmd/nvedit.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/cmd/nvedit.c b/cmd/nvedit.c index ddc715b4f91..1c8d49646e5 100644 --- a/cmd/nvedit.c +++ b/cmd/nvedit.c @@ -62,11 +62,13 @@ DECLARE_GLOBAL_DATA_PTR;
#endif
+#if CONFIG_IS_ENABLED(ENV_SUPPORT) #if !defined(ENV_IS_IN_DEVICE) && \ !defined(CONFIG_ENV_IS_NOWHERE) # error Define one of CONFIG_ENV_IS_IN_{EEPROM|FLASH|MMC|FAT|EXT4|\ NAND|NVRAM|ONENAND|SATA|SPI_FLASH|REMOTE|UBI} or CONFIG_ENV_IS_NOWHERE #endif +#endif /* ENV_SUPPORT */
/* * Maximum expected input data size for import command

This is written incorrectly, since SPL_ should not be used with the CONFIG_IS_ENABLED macro. Fix it by dropping the prefix and inverting the logic, which produces the same result as now.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/x86/cpu/qemu/qemu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/x86/cpu/qemu/qemu.c b/arch/x86/cpu/qemu/qemu.c index e54082df7f9..274978c023b 100644 --- a/arch/x86/cpu/qemu/qemu.c +++ b/arch/x86/cpu/qemu/qemu.c @@ -97,7 +97,7 @@ static void qemu_chipset_init(void) } }
-#if !CONFIG_IS_ENABLED(SPL_X86_32BIT_INIT) +#if CONFIG_IS_ENABLED(X86_32BIT_INIT) int arch_cpu_init(void) { post_code(POST_CPU_INIT);

At present we rely on this not existing to avoid building ACPI for SPL. But with the new split configs this does not work. Add a separate Kconfig instead.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/core/Kconfig | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/drivers/core/Kconfig b/drivers/core/Kconfig index 9ae188c1dfc..4c2aeb8bce5 100644 --- a/drivers/core/Kconfig +++ b/drivers/core/Kconfig @@ -332,6 +332,11 @@ config ACPIGEN things like generating device-specific tables and returning the ACPI name of a device.
+config SPL_ACPIGEN + def_bool n + help + Dummy option to ensure that ACPI tables are not generated in SPL. + config BOUNCE_BUFFER bool "Include bounce buffer API" help

At present we rely on this not existing to avoid building various command-line features.
But with the new split configs this does not work. Add separates Kconfigs instead.
Signed-off-by: Simon Glass sjg@chromium.org ---
cmd/Kconfig | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/cmd/Kconfig b/cmd/Kconfig index 3a857b3f6e2..f469739a5fe 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -23,6 +23,16 @@ config HUSH_PARSER If disabled, you get the old, much simpler behaviour with a somewhat smaller memory footprint.
+config SPL_CMDLINE + def_bool n + help + Dummy option to ensure that the command line is not enabled in SPL. + +config SPL_HUSH_PARSER + def_bool n + help + Dummy option to ensure that the hush parser is not enabled in SPL. + config CMDLINE_EDITING bool "Enable command line editing" depends on CMDLINE

At present we rely on this not existing to avoid building various EC features.
But with the new split configs this does not work. Add separates Kconfigs instead.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/i2c/Kconfig | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig index 63d03a3cebf..4c3a084b4f8 100644 --- a/drivers/i2c/Kconfig +++ b/drivers/i2c/Kconfig @@ -57,6 +57,11 @@ config I2C_CROS_EC_TUNNEL I2C or LPC). Some Chromebooks use this when the hardware design does not allow direct access to the main PMIC from the AP.
+config SPL_I2C_CROS_EC_TUNNEL + def_bool n + help + Dummy option to ensure that this feature is not enabled in SPL. + config I2C_CROS_EC_LDO bool "Provide access to LDOs on the Chrome OS EC" depends on CROS_EC @@ -71,6 +76,11 @@ config I2C_CROS_EC_LDO avoid duplicating the logic in the TPS65090 regulator driver for enabling/disabling an LDO.
+config SPL_I2C_CROS_EC_LDO + def_bool n + help + Dummy option to ensure that this feature is not enabled in SPL. + config I2C_SET_DEFAULT_BUS_NUM bool "Set default I2C bus number" depends on DM_I2C

At present we rely on this not existing to avoid building the emulator for SPL.
But with the new split configs this does not work. Add a separate Kconfig instead.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/power/acpi_pmc/Kconfig | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/drivers/power/acpi_pmc/Kconfig b/drivers/power/acpi_pmc/Kconfig index fcd50e36cad..d3f363b0dcf 100644 --- a/drivers/power/acpi_pmc/Kconfig +++ b/drivers/power/acpi_pmc/Kconfig @@ -32,3 +32,8 @@ config ACPI_PMC_SANDBOX the uclass logic can be tested. You can use the 'pmc' command to access information from the driver. It uses I/O access to read from the PMC. + +config SPL_ACPI_PMC_SANDBOX + def_bool n + help + Dummy option to ensure that this feature is not enabled in SPL.

At present we rely on this not existing to avoid building these tests for SPL.
But with the new split configs this does not work. Add a separate Kconfig instead.
Signed-off-by: Simon Glass sjg@chromium.org ---
test/Kconfig | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/test/Kconfig b/test/Kconfig index e15ba239eb3..52d85ca78a2 100644 --- a/test/Kconfig +++ b/test/Kconfig @@ -69,6 +69,11 @@ config UT_COMPRESSION Enables tests for compression and decompression routines for simple sanity and for buffer overflow conditions.
+config SPL_UT_COMPRESSION + def_bool n + help + Dummy option to ensure that this feature is not enabled in SPL. + config UT_LOG bool "Unit tests for logging functions" depends on UNIT_TEST

At present this is always enabled in SPL by virtue of the Makefile condition, which ignores SPL. Add the required config to tidy this up, so it will works with split configs.
Signed-off-by: Simon Glass sjg@chromium.org ---
configs/sandbox_noinst_defconfig | 1 + configs/sandbox_spl_defconfig | 1 + 2 files changed, 2 insertions(+)
diff --git a/configs/sandbox_noinst_defconfig b/configs/sandbox_noinst_defconfig index 88443f5ab27..b1f3737bb01 100644 --- a/configs/sandbox_noinst_defconfig +++ b/configs/sandbox_noinst_defconfig @@ -131,6 +131,7 @@ CONFIG_LED_GPIO=y CONFIG_DM_MAILBOX=y CONFIG_SANDBOX_MBOX=y CONFIG_MISC=y +CONFIG_SPL_MISC=y CONFIG_CROS_EC=y CONFIG_CROS_EC_I2C=y CONFIG_CROS_EC_LPC=y diff --git a/configs/sandbox_spl_defconfig b/configs/sandbox_spl_defconfig index 77dd83cf6fd..1e54edf66ac 100644 --- a/configs/sandbox_spl_defconfig +++ b/configs/sandbox_spl_defconfig @@ -133,6 +133,7 @@ CONFIG_LED_GPIO=y CONFIG_DM_MAILBOX=y CONFIG_SANDBOX_MBOX=y CONFIG_MISC=y +CONFIG_SPL_MISC=y CONFIG_CROS_EC=y CONFIG_CROS_EC_I2C=y CONFIG_CROS_EC_LPC=y

There is no need to check for SPL/TPL build again as the 'ifdef' above does this already. Drop it, so that the build rule works with split configs.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/serial/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index 3cbea8156f8..4b723faf79b 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -5,7 +5,7 @@
ifdef CONFIG_SPL_BUILD
-ifeq ($(CONFIG_$(SPL_TPL_)BUILD)$(CONFIG_$(SPL_TPL_)DM_SERIAL),yy) +ifeq ($(CONFIG_$(SPL_TPL_)DM_SERIAL),y) obj-y += serial-uclass.o else obj-y += serial.o

At present we rely on this not existing to avoid building virtio for SPL.
But with the new split configs this does not work. Add a separate Kconfig instead.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/virtio/Kconfig | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/drivers/virtio/Kconfig b/drivers/virtio/Kconfig index 863c3fbe029..2ac98edff58 100644 --- a/drivers/virtio/Kconfig +++ b/drivers/virtio/Kconfig @@ -22,6 +22,12 @@ config VIRTIO This option is selected by any driver which implements the virtio transport, such as CONFIG_VIRTIO_MMIO or CONFIG_VIRTIO_PCI.
+config SPL_VIRTIO + bool + help + This option is selected by any driver which implements the virtio + transport, such as CONFIG_VIRTIO_MMIO or CONFIG_VIRTIO_PCI. + config VIRTIO_MMIO bool "Platform bus driver for memory mapped virtio devices" select VIRTIO

Separate out the code that writes the Makefile and headers so we can reuse these functions when writing out SPL files.
This makes no functional change.
Signed-off-by: Simon Glass sjg@chromium.org ---
scripts/kconfig/confdata.c | 65 ++++++++++++++++++++++---------------- scripts/kconfig/expr.h | 9 ++++++ scripts/kconfig/lkc.h | 9 ++++++ 3 files changed, 56 insertions(+), 27 deletions(-)
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index d587b10d7f8..73bf43bcb95 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -509,27 +509,18 @@ int conf_read(const char *name) return 0; }
-/* - * Kconfig configuration printer - * - * This printer is used when generating the resulting configuration after - * kconfig invocation and `defconfig' files. Unset symbol might be omitted by - * passing a non-NULL argument to the printer. - * - */ -static void -kconfig_print_symbol(FILE *fp, struct symbol *sym, const char *value, void *arg) +/* Print a symbol for a Makefile */ +static void print_makefile_sym(FILE *fp, const char *name, + enum symbol_type type, const char *value, + bool skip_unset) { - - switch (sym->type) { + switch (type) { case S_BOOLEAN: case S_TRISTATE: if (*value == 'n') { - bool skip_unset = (arg != NULL); - if (!skip_unset) fprintf(fp, "# %s%s is not set\n", - CONFIG_, sym->name); + CONFIG_, name); return; } break; @@ -537,7 +528,21 @@ kconfig_print_symbol(FILE *fp, struct symbol *sym, const char *value, void *arg) break; }
- fprintf(fp, "%s%s=%s\n", CONFIG_, sym->name, value); + fprintf(fp, "%s%s=%s\n", CONFIG_, name, value); +} + +/* + * Kconfig configuration printer + * + * This printer is used when generating the resulting configuration after + * kconfig invocation and `defconfig' files. Unset symbol might be omitted by + * passing a non-NULL argument to the printer. + * + */ +static void +kconfig_print_symbol(FILE *fp, struct symbol *sym, const char *value, void *arg) +{ + print_makefile_sym(fp, sym->name, sym->type, value, arg != NULL); }
static void @@ -566,16 +571,12 @@ static struct conf_printer kconfig_printer_cb = .print_comment = kconfig_print_comment, };
-/* - * Header printer - * - * This printer is used when generating the `include/generated/autoconf.h' file. - */ -static void -header_print_symbol(FILE *fp, struct symbol *sym, const char *value, void *arg) +/* Print a symbol for a header file */ +static void print_header_sym(FILE *fp, const char *name, enum symbol_type type, + const char *value) {
- switch (sym->type) { + switch (type) { case S_BOOLEAN: case S_TRISTATE: { const char *suffix = ""; @@ -588,7 +589,7 @@ header_print_symbol(FILE *fp, struct symbol *sym, const char *value, void *arg) /* fall through */ default: fprintf(fp, "#define %s%s%s 1\n", - CONFIG_, sym->name, suffix); + CONFIG_, name, suffix); } break; } @@ -598,18 +599,28 @@ header_print_symbol(FILE *fp, struct symbol *sym, const char *value, void *arg) if (value[0] != '0' || (value[1] != 'x' && value[1] != 'X')) prefix = "0x"; fprintf(fp, "#define %s%s %s%s\n", - CONFIG_, sym->name, prefix, value); + CONFIG_, name, prefix, value); break; } case S_STRING: case S_INT: fprintf(fp, "#define %s%s %s\n", - CONFIG_, sym->name, value); + CONFIG_, name, value); break; default: break; } +}
+/* + * Header printer + * + * This printer is used when generating the `include/generated/autoconf.h' file. + */ +static void +header_print_symbol(FILE *fp, struct symbol *sym, const char *value, void *arg) +{ + print_header_sym(fp, sym->name, sym->type, value); }
static void diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h index 7c329e17900..656c87fb4f3 100644 --- a/scripts/kconfig/expr.h +++ b/scripts/kconfig/expr.h @@ -158,6 +158,15 @@ struct symbol { /* Set symbol to y if allnoconfig; used for symbols that hide others */ #define SYMBOL_ALLNOCONFIG_Y 0x200000
+/* U-Boot: Marks an SPL symbol */ +#define SYMBOL_SPL 0x400000 + +/* U-Boot: Marks a non-SPL symbol that also has an SPL version */ +#define SYMBOL_HAS_SPL 0x800000 + +/* U-Boot: Marks an-SPL symbol that does not have a non-SPL version */ +#define SYMBOL_SPL_ONLY 0x1000000 + #define SYMBOL_MAXLENGTH 256 #define SYMBOL_HASHSIZE 9973
diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h index 9eb7c837cd8..dec03cc927a 100644 --- a/scripts/kconfig/lkc.h +++ b/scripts/kconfig/lkc.h @@ -71,6 +71,15 @@ void sym_add_change_count(int count); bool conf_set_all_new_symbols(enum conf_def_mode mode); void set_all_choice_values(struct symbol *csym);
+/** + * conf_mark_spl_symbols() - Mark SPL symbols + * + * Symbols which don't start with SPL_ (TPL_, etc.) but have an SPL version + * should be marked with the SYMBOL_SPL flag, so we know to avoid writing them + * in the SPL autoconf.h files. + */ +void conf_mark_spl_symbols(void); + /* confdata.c and expr.c */ static inline void xfwrite(const void *str, size_t len, size_t count, FILE *out) {

At present kconfig writes out several files, including:
auto.conf - CONFIG settings used by make autoconf.h - header file used by C code
This works well but is a bit ugly in places, for example requiring the use of a SPL_TPL_ macro in Makefiles to distinguish between options intended for SPL and U-Boot proper.
Update the kconfig tool to also output separate files for each phase: e.g. auto_spl.conf and autoconf_spl.h
These are similar to the existing file, but drop the SPL_ prefix so that SPL_TPL_ is not needed. It also allows the CONFIG_IS_ENABLED() macro to be simplified, in a later patch.
The output of existing files is not changed in any way, This commit just adds new ones.
These changes may benefit from some reworking to send upstream, e.g. to use a struct for the 'arg' parameter.
Signed-off-by: Simon Glass sjg@chromium.org ---
scripts/kconfig/conf.c | 4 + scripts/kconfig/confdata.c | 229 ++++++++++++++++++++++++++++++++++++- 2 files changed, 231 insertions(+), 2 deletions(-)
diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index 376f796f674..0104180817e 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c @@ -684,6 +684,10 @@ int main(int ac, char **av) break; }
+ /* U-Boot: Mark SPL symbols */ + if (sync_kconfig) + conf_mark_spl_symbols(); + if (sync_kconfig) { /* syncconfig is used during the build so we shall update autoconf. * All other commands are only used to generate a config. diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 73bf43bcb95..5b6bf927a7a 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -16,6 +16,15 @@
#include "lkc.h"
+/* Number of SPL prefixes we recognise */ +#define NUM_SPLS 2 + +/* + * SPL prefixes recognised. For example CONFIG_SPL_xxx is considered to be an + * SPL version of CONFIG_xxx + */ +static const char *spl_name[NUM_SPLS] = {"SPL", "TPL"}; + /* return true if 'path' exists, false otherwise */ static bool is_present(const char *path) { @@ -571,11 +580,77 @@ static struct conf_printer kconfig_printer_cb = .print_comment = kconfig_print_comment, };
+/** + * get_spl_name() - Look up an SPL symbol + * + * This is used to get the name of a Kconfig option to write in an SPL context. + * If the symbol has an SPL symbol, this means it is used for U-Boot proper, so + * should not be written at all. + * + * Otherwise, this returns the name of the option. If the option is an SPL + * option, then the prefix (SPL_ or TPL_) is removed + * + * @sym: Symbol to look up + * @arg: Argument passed to the symbol function. This is void * but is actually + * an int, indicating the SPL index / type (see spl_name[]) + * @return name to write out for this symbol xxx: + * NULL (don't write) if xxx has an associated SPL symbol + * xxx if xxx is a non-SPL symbol + * xxx if SPL_xxx is an SPL symbol + */ +static const char *get_spl_name(const struct symbol *sym, const void *arg) +{ + int spl = (long)arg; + const char *name = sym->name; + + /* Don't print it if this has an SPL symbol */ + if (sym->flags & SYMBOL_HAS_SPL) + return NULL; + + /* + * If it is SPL, only print it if the SPL_ prefix matches + * Drop the prefix. + */ + if (sym->flags & SYMBOL_SPL) { + int len = strlen(spl_name[spl]); + + if (!strncmp(name, spl_name[spl], len) && name[len] == '_') + name += len + 1; + } + + return name; +} + +/* + * Kconfig configuration printer for SPL + * + * This printer is used when generating the resulting configuration after + * kconfig invocation and `defconfig' files. Unset symbol might be omitted by + * passing a non-NULL argument to the printer. + * + */ +static void spl_kconfig_print_symbol(FILE *fp, struct symbol *sym, + const char *value, void *arg) +{ + const char *name; + + name = get_spl_name(sym, arg); + if (!name) + return; + + print_makefile_sym(fp, name, sym->type, value, false); + print_makefile_sym(fp, sym->name, sym->type, value, false); +} + +static struct conf_printer spl_kconfig_printer_cb = { + .print_symbol = spl_kconfig_print_symbol, + .print_comment = kconfig_print_comment, +}; + /* Print a symbol for a header file */ static void print_header_sym(FILE *fp, const char *name, enum symbol_type type, const char *value) { - switch (type) { case S_BOOLEAN: case S_TRISTATE: { @@ -651,6 +726,35 @@ static struct conf_printer header_printer_cb = .print_comment = header_print_comment, };
+/* + * SPL header printer + * + * This printer is used when generating SPL files such as + * `include/generated/autoconf_spl.h' + */ +static void spl_header_print_symbol(FILE *fp, struct symbol *sym, + const char *value, void *arg) +{ + const char *name; + + name = get_spl_name(sym, arg); + if (!name) + return; + + if (!(sym->flags & (SYMBOL_SPL | SYMBOL_HAS_SPL))) { + /* This symbol cannot be used by CONFIG_IS_ENABLED() */ + fprintf(fp, "#define %s%s_nospl 1\n", CONFIG_, name); + } + + print_header_sym(fp, name, sym->type, value); + print_header_sym(fp, sym->name, sym->type, value); +} + +static struct conf_printer spl_header_printer_cb = { + .print_symbol = spl_header_print_symbol, + .print_comment = header_print_comment, +}; + /* * Tristate printer * @@ -1027,7 +1131,9 @@ int conf_write_autoconf(void) struct symbol *sym; const char *name; FILE *out, *tristate, *out_h; - int i; + FILE *out_spl[NUM_SPLS]; + FILE *out_h_spl[NUM_SPLS]; + int i, spl;
sym_clear_all_valid();
@@ -1053,12 +1159,51 @@ int conf_write_autoconf(void) return 1; }
+ for (spl = 0; spl < NUM_SPLS; spl++) { + char fname[80]; + + snprintf(fname, sizeof(fname), ".tmpconfig_%s", + spl_name[spl]); + + out_spl[spl] = fopen(fname, "w"); + if (!out_spl[spl]) { + while (spl--) { + fclose(out_spl[spl]); + fclose(out_h_spl[spl]); + } + fclose(out_h); + fclose(out); + fclose(tristate); + return 1; + } + + snprintf(fname, sizeof(fname), ".tmpconfig_%s.h", + spl_name[spl]); + + out_h_spl[spl] = fopen(fname, "w"); + if (!out_h_spl[spl]) { + fclose(out_spl[spl]); + while (spl--) { + fclose(out_spl[spl]); + fclose(out_h_spl[spl]); + } + fclose(out_h); + fclose(out); + fclose(tristate); + return 1; + } + } + conf_write_heading(out, &kconfig_printer_cb, NULL);
conf_write_heading(tristate, &tristate_printer_cb, NULL);
conf_write_heading(out_h, &header_printer_cb, NULL);
+ for (spl = 0; spl < NUM_SPLS; spl++) + conf_write_heading(out_h_spl[spl], &spl_header_printer_cb, + (void *)(long)spl); + for_all_symbols(i, sym) { sym_calc_value(sym); if (!(sym->flags & SYMBOL_WRITE) || !sym->name) @@ -1070,10 +1215,22 @@ int conf_write_autoconf(void) conf_write_symbol(tristate, sym, &tristate_printer_cb, (void *)1);
conf_write_symbol(out_h, sym, &header_printer_cb, NULL); + + for (spl = 0; spl < NUM_SPLS; spl++) { + conf_write_symbol(out_spl[spl], sym, + &spl_kconfig_printer_cb, + (void *)(long)spl); + + conf_write_symbol(out_h_spl[spl], sym, + &spl_header_printer_cb, + (void *)(long)spl); + } } fclose(out); fclose(tristate); fclose(out_h); + for (spl = 0; spl < NUM_SPLS; spl++) + fclose(out_h_spl[spl]);
name = getenv("KCONFIG_AUTOHEADER"); if (!name) @@ -1083,6 +1240,29 @@ int conf_write_autoconf(void) if (rename(".tmpconfig.h", name)) return 1;
+ for (spl = 0; spl < NUM_SPLS; spl++) { + char tmpname[80], fname[80]; + char *s; + + snprintf(tmpname, sizeof(tmpname), ".tmpconfig_%s.h", + spl_name[spl]); + snprintf(fname, sizeof(fname), + "include/generated/autoconf_%s.h", spl_name[spl]); + for (s = fname; *s; s++) + *s = tolower(*s); + if (rename(tmpname, fname)) + return 1; + + snprintf(tmpname, sizeof(tmpname), ".tmpconfig_%s", + spl_name[spl]); + snprintf(fname, sizeof(fname), + "include/config/auto_%s.conf", spl_name[spl]); + for (s = fname; *s; s++) + *s = tolower(*s); + if (rename(tmpname, fname)) + return 1; + } + name = getenv("KCONFIG_TRISTATE"); if (!name) name = "include/config/tristate.conf"; @@ -1326,3 +1506,48 @@ bool conf_set_all_new_symbols(enum conf_def_mode mode)
return has_changed; } + +static bool is_spl(const char *name, int *lenp) +{ + const char *uscore; + int len; + int i; + + uscore = strchr(name, '_'); + if (!uscore) + return false; + + len = uscore - name; + for (i = 0; i < NUM_SPLS; i++) { + if (len == strlen(spl_name[i]) && + !strncmp(name, spl_name[i], len)) { + *lenp = len; + return true; + } + } + + return false; +} + +void conf_mark_spl_symbols(void) +{ + struct symbol *sym; + int i; + + for_all_symbols(i, sym) if (sym->name) { + int len; + bool spl = is_spl(sym->name, &len); + + if (spl) { + struct symbol *non_spl; + + sym->flags |= SYMBOL_SPL; + non_spl = sym_find(sym->name + len + 1); + if (non_spl) + non_spl->flags |= SYMBOL_HAS_SPL; + else + sym->flags |= SYMBOL_SPL_ONLY; + } + } +} +

At present there is only a single auto.conf file used within the makefiles. Update them to use the correct one for each phase.
Signed-off-by: Simon Glass sjg@chromium.org ---
Makefile | 11 ++++++++++- scripts/Makefile.build | 10 +++++++++- scripts/Makefile.spl | 8 +++++++- 3 files changed, 26 insertions(+), 3 deletions(-)
diff --git a/Makefile b/Makefile index 3014788e14e..0bf846b5640 100644 --- a/Makefile +++ b/Makefile @@ -581,8 +581,17 @@ scripts: scripts_basic scripts_dtc include/config/auto.conf $(Q)$(MAKE) $(build)=$(@)
ifeq ($(dot-config),1) -# Read in config + +# Read in the config for this phase +ifdef CONFIG_TPL_BUILD +-include include/config/auto_tpl.conf +else +ifdef CONFIG_SPL_BUILD +-include include/config/auto_spl.conf +else -include include/config/auto.conf +endif +endif
# Read in dependencies to all Kconfig* files, make sure to run # oldconfig if changes are detected. diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 5df8f61aa58..aaa960b51ce 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -40,9 +40,17 @@ ldflags-y := subdir-asflags-y := subdir-ccflags-y :=
-# Read auto.conf if it exists, otherwise ignore +# Read appropriate auto.conf if it exists, otherwise ignore # Modified for U-Boot + +ifeq ($(SPL_NAME),tpl) +-include include/config/auto_tpl.conf +else ifeq ($(SPL_NAME),spl) +-include include/config/auto_spl.conf +else -include include/config/auto.conf +endif + -include $(prefix)/include/autoconf.mk include scripts/Makefile.uncmd_spl
diff --git a/scripts/Makefile.spl b/scripts/Makefile.spl index 25a3e7fa52e..02dd85b8e1c 100644 --- a/scripts/Makefile.spl +++ b/scripts/Makefile.spl @@ -19,9 +19,15 @@ _dummy := $(shell [ -d $(obj) ] || mkdir -p $(obj))
include $(srctree)/scripts/Kbuild.include
--include include/config/auto.conf -include $(obj)/include/autoconf.mk
+# Read in the config for this SPL phase +ifdef CONFIG_TPL_BUILD +-include include/config/auto_tpl.conf +else +-include include/config/auto_spl.conf +endif + UBOOTINCLUDE := -I$(obj)/include $(UBOOTINCLUDE)
KBUILD_CPPFLAGS += -DCONFIG_SPL_BUILD

Now that we include an auto.conf file specific to the phase being built we can make these variables empty.
With this done, we can also remove them from U-Boot entirely, dropping them from all Makefiles. That is left for a future clean-up since we cannot apply this series until CONFIG migration is complete.
Signed-off-by: Simon Glass sjg@chromium.org ---
scripts/Kbuild.include | 17 +++++++++++++---- scripts/Makefile.spl | 17 +++++++++++++---- 2 files changed, 26 insertions(+), 8 deletions(-)
diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include index a745cc4fccd..90444d38f89 100644 --- a/scripts/Kbuild.include +++ b/scripts/Kbuild.include @@ -319,14 +319,23 @@ endif # do not delete intermediate files automatically .SECONDARY:
+# The SPL_ and SPL_TPL_ vars resolve to nothing so they can be used in +# Makefiles + +# For compatibility with ad-hoc CONFIG options, provide xSPL_ and xSPL_TPL_ +# which maintain the old behaviour. The is just for illustration purposes, +# since it is better to wait until all CONFIGs are migrated. ifdef CONFIG_SPL_BUILD -SPL_ := SPL_ +xSPL_ := SPL_ ifeq ($(CONFIG_TPL_BUILD),y) -SPL_TPL_ := TPL_ +xSPL_TPL_ := TPL_ else -SPL_TPL_ := SPL_ +xSPL_TPL_ := SPL_ endif else +xSPL_ := +xSPL_TPL_ := +endif + SPL_ := SPL_TPL_ := -endif diff --git a/scripts/Makefile.spl b/scripts/Makefile.spl index 02dd85b8e1c..a6705efcf07 100644 --- a/scripts/Makefile.spl +++ b/scripts/Makefile.spl @@ -45,17 +45,26 @@ endif
export SPL_NAME
+# The SPL_ and SPL_TPL_ vars resolve to nothing so they can be used in +# Makefiles + +# For compatibility with ad-hoc CONFIG options, provide xSPL_ and xSPL_TPL_ +# which maintain the old behaviour. The is just for illustration purposes, +# since it is better to wait until all CONFIGs are migrated. ifdef CONFIG_SPL_BUILD -SPL_ := SPL_ +xSPL_ := SPL_ ifeq ($(CONFIG_TPL_BUILD),y) -SPL_TPL_ := TPL_ +xSPL_TPL_ := TPL_ else -SPL_TPL_ := SPL_ +xSPL_TPL_ := SPL_ endif else +xSPL_ := +xSPL_TPL_ := +endif + SPL_ := SPL_TPL_ := -endif
ifeq ($(obj)$(CONFIG_SUPPORT_SPL),spl) $(error You cannot build SPL without enabling CONFIG_SUPPORT_SPL)

Ad-hoc CONFIGs are not supported by the new split-config mechanism. Use the provided work-around for these symbols, just to show the mechanism.
Signed-off-by: Simon Glass sjg@chromium.org ---
scripts/Makefile.spl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/scripts/Makefile.spl b/scripts/Makefile.spl index a6705efcf07..8baf8478f64 100644 --- a/scripts/Makefile.spl +++ b/scripts/Makefile.spl @@ -198,11 +198,11 @@ LDPPFLAGS += \
# Turn various CONFIG symbols into IMAGE symbols for easy reuse of # the scripts between SPL and TPL. -ifneq ($(CONFIG_$(SPL_TPL_)MAX_SIZE),) -LDPPFLAGS += -DIMAGE_MAX_SIZE=$(CONFIG_$(SPL_TPL_)MAX_SIZE) +ifneq ($(CONFIG_$(xSPL_TPL_)MAX_SIZE),) +LDPPFLAGS += -DIMAGE_MAX_SIZE=$(CONFIG_$(xSPL_TPL_)MAX_SIZE) endif -ifneq ($(CONFIG_$(SPL_TPL_)TEXT_BASE),) -LDPPFLAGS += -DIMAGE_TEXT_BASE=$(CONFIG_$(SPL_TPL_)TEXT_BASE) +ifneq ($(CONFIG_$(xSPL_TPL_)TEXT_BASE),) +LDPPFLAGS += -DIMAGE_TEXT_BASE=$(CONFIG_$(xSPL_TPL_)TEXT_BASE) endif
MKIMAGEOUTPUT ?= /dev/null

Update this file to include the correct autoconf.h or autoconf_spl.h file for each phase. This allows the macros to be simplified.
With this, CONFIG_IS_ENABLED() is the same as IS_ENABLED() apart from a migration detail.
Signed-off-by: Simon Glass sjg@chromium.org ---
include/linux/kconfig.h | 87 ++++++++++++----------------------------- 1 file changed, 24 insertions(+), 63 deletions(-)
diff --git a/include/linux/kconfig.h b/include/linux/kconfig.h index d109ed3119e..e6b0f238ec4 100644 --- a/include/linux/kconfig.h +++ b/include/linux/kconfig.h @@ -1,7 +1,13 @@ #ifndef __LINUX_KCONFIG_H #define __LINUX_KCONFIG_H
+#ifdef CONFIG_TPL_BUILD +#include <generated/autoconf_tpl.h> +#elif defined(CONFIG_SPL_BUILD) +#include <generated/autoconf_spl.h> +#else #include <generated/autoconf.h> +#endif
/* * Helper macros to use CONFIG_ options in C/CPP expressions. Note that @@ -31,29 +37,29 @@ (config_enabled(option))
/* - * U-Boot add-on: Helper macros to reference to different macros - * (CONFIG_ or CONFIG_SPL_ prefixed), depending on the build context. + * The _nospl version of a CONFIG is emitted by kconfig when an option has no + * SPL equivalent. So in that case there is a CONFIG_xxx for example, but not a + * CONFIG_SPL_xxx + * + * This is needed as a transition measure while CONFIG_IS_ENABLED() is used on + * options without SPL equivalent, since in that case it should always return + * zero. Once we add SPL equivalents, this clause can be dropped. */
-#if defined(CONFIG_TPL_BUILD) -#define _CONFIG_PREFIX TPL_ -#elif defined(CONFIG_SPL_BUILD) -#define _CONFIG_PREFIX SPL_ -#else -#define _CONFIG_PREFIX -#endif - -#define config_val(cfg) _config_val(_CONFIG_PREFIX, cfg) -#define _config_val(pfx, cfg) __config_val(pfx, cfg) -#define __config_val(pfx, cfg) CONFIG_ ## pfx ## cfg +#define __config_is_enabled(cfg) (IS_ENABLED(CONFIG_ ## cfg ## _nospl) ? \ + !IS_ENABLED(CONFIG_SPL_BUILD) : \ + config_enabled(CONFIG_ ## cfg))
/* - * CONFIG_VAL(FOO) evaluates to the value of - * CONFIG_FOO if CONFIG_SPL_BUILD is undefined, - * CONFIG_SPL_FOO if CONFIG_SPL_BUILD is defined. - * CONFIG_TPL_FOO if CONFIG_TPL_BUILD is defined. + * CONFIG_IS_ENABLED(FOO) returns 1 if CONFIG_FOO is enabled for the phase being + * built, else 0. Note that CONFIG_FOO corresponds to CONFIG_SPL_FOO (in + * Kconfig) for the SPL phase, CONFIG_TPL_FOO for the TPL phase, etc. */ -#define CONFIG_VAL(option) config_val(option) +#define CONFIG_IS_ENABLED(option) __config_is_enabled(option) + +#define __config_val(cfg) CONFIG_ ## cfg + +#define CONFIG_VAL(option) __config_val(option)
/* * Count number of arguments to a variadic macro. Currently only need @@ -62,49 +68,4 @@ #define __arg6(a1, a2, a3, a4, a5, a6, ...) a6 #define __count_args(...) __arg6(dummy, ##__VA_ARGS__, 4, 3, 2, 1, 0)
-#define __concat(a, b) ___concat(a, b) -#define ___concat(a, b) a ## b - -#define __unwrap(...) __VA_ARGS__ -#define __unwrap1(case1, case0) __unwrap case1 -#define __unwrap0(case1, case0) __unwrap case0 - -#define __CONFIG_IS_ENABLED_1(option) __CONFIG_IS_ENABLED_3(option, (1), (0)) -#define __CONFIG_IS_ENABLED_2(option, case1) __CONFIG_IS_ENABLED_3(option, case1, ()) -#define __CONFIG_IS_ENABLED_3(option, case1, case0) \ - __concat(__unwrap, config_enabled(CONFIG_VAL(option))) (case1, case0) - -/* - * CONFIG_IS_ENABLED(FOO) expands to - * 1 if CONFIG_SPL_BUILD is undefined and CONFIG_FOO is set to 'y', - * 1 if CONFIG_SPL_BUILD is defined and CONFIG_SPL_FOO is set to 'y', - * 1 if CONFIG_TPL_BUILD is defined and CONFIG_TPL_FOO is set to 'y', - * 0 otherwise. - * - * CONFIG_IS_ENABLED(FOO, (abc)) expands to - * abc if CONFIG_SPL_BUILD is undefined and CONFIG_FOO is set to 'y', - * abc if CONFIG_SPL_BUILD is defined and CONFIG_SPL_FOO is set to 'y', - * abc if CONFIG_TPL_BUILD is defined and CONFIG_TPL_FOO is set to 'y', - * nothing otherwise. - * - * CONFIG_IS_ENABLED(FOO, (abc), (def)) expands to - * abc if CONFIG_SPL_BUILD is undefined and CONFIG_FOO is set to 'y', - * abc if CONFIG_SPL_BUILD is defined and CONFIG_SPL_FOO is set to 'y', - * abc if CONFIG_TPL_BUILD is defined and CONFIG_TPL_FOO is set to 'y', - * def otherwise. - * - * The optional second and third arguments must be parenthesized; that - * allows one to include a trailing comma, e.g. for use in - * - * CONFIG_IS_ENABLED(ACME, ({.compatible = "acme,frobnozzle"},)) - * - * which adds an entry to the array being defined if CONFIG_ACME (or - * CONFIG_SPL_ACME/CONFIG_TPL_ACME, depending on build context) is - * set, and nothing otherwise. - */ - -#define CONFIG_IS_ENABLED(option, ...) \ - __concat(__CONFIG_IS_ENABLED_, __count_args(option, ##__VA_ARGS__)) (option, ##__VA_ARGS__) - - #endif /* __LINUX_KCONFIG_H */

It is annoying to have to use IS_ENABLED() and CONFIG_IS_ENABLED(), depending on whether the option being checked has an SPL version. Also we use #ifdef CONFIG_xxx and #if defined(CONFIG_xxx) in some contexts. It would be nice to use a single style consistenty.
Add a CONFIG() macro to this end, to check configuration. The argument is the Kconfig name to check, excluding any SPL_/TPL_ prefix, for example:
CONFIG(DM) CONFIG(CMD_MISC) CONFIG(OF_PLATDATA)
This is just for illustration, but it should be possible to drop IS_ENABLED() and CONFIG_IS_ENABLED(), once migration of ad-hoc CONFIG is complete. The use of #ifdef and defined() can be updated also.
Signed-off-by: Simon Glass sjg@chromium.org ---
include/linux/kconfig.h | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-)
diff --git a/include/linux/kconfig.h b/include/linux/kconfig.h index e6b0f238ec4..401341275fe 100644 --- a/include/linux/kconfig.h +++ b/include/linux/kconfig.h @@ -28,14 +28,6 @@ #define __config_enabled(arg1_or_junk) ___config_enabled(arg1_or_junk 1, 0) #define ___config_enabled(__ignored, val, ...) val
-/* - * IS_ENABLED(CONFIG_FOO) evaluates to 1 if CONFIG_FOO is set to 'y', - * 0 otherwise. - * - */ -#define IS_ENABLED(option) \ - (config_enabled(option)) - /* * The _nospl version of a CONFIG is emitted by kconfig when an option has no * SPL equivalent. So in that case there is a CONFIG_xxx for example, but not a @@ -51,11 +43,11 @@ config_enabled(CONFIG_ ## cfg))
/* - * CONFIG_IS_ENABLED(FOO) returns 1 if CONFIG_FOO is enabled for the phase being + * CONFIG(FOO) returns 1 if CONFIG_FOO is enabled for the phase being * built, else 0. Note that CONFIG_FOO corresponds to CONFIG_SPL_FOO (in * Kconfig) for the SPL phase, CONFIG_TPL_FOO for the TPL phase, etc. */ -#define CONFIG_IS_ENABLED(option) __config_is_enabled(option) +#define CONFIG(option) __config_is_enabled(option)
#define __config_val(cfg) CONFIG_ ## cfg
participants (1)
-
Simon Glass