diff options
Diffstat (limited to 'arch/x86/lib')
-rw-r--r-- | arch/x86/lib/Makefile | 1 | ||||
-rw-r--r-- | arch/x86/lib/acpi_nhlt.c | 482 | ||||
-rw-r--r-- | arch/x86/lib/acpi_table.c | 87 | ||||
-rw-r--r-- | arch/x86/lib/coreboot_table.c | 6 | ||||
-rw-r--r-- | arch/x86/lib/fsp/fsp_common.c | 4 | ||||
-rw-r--r-- | arch/x86/lib/fsp/fsp_dram.c | 26 | ||||
-rw-r--r-- | arch/x86/lib/fsp1/fsp_common.c | 16 | ||||
-rw-r--r-- | arch/x86/lib/fsp2/fsp_dram.c | 7 | ||||
-rw-r--r-- | arch/x86/lib/fsp2/fsp_meminit.c | 24 | ||||
-rw-r--r-- | arch/x86/lib/fsp2/fsp_silicon_init.c | 1 | ||||
-rw-r--r-- | arch/x86/lib/tables.c | 38 | ||||
-rw-r--r-- | arch/x86/lib/zimage.c | 10 |
12 files changed, 634 insertions, 68 deletions
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile index 1079bf2022..1185a88c27 100644 --- a/arch/x86/lib/Makefile +++ b/arch/x86/lib/Makefile @@ -22,6 +22,7 @@ obj-y += init_helpers.o obj-y += interrupts.o obj-y += lpc-uclass.o obj-y += mpspec.o +obj-$(CONFIG_$(SPL_TPL_)ACPIGEN) += acpi_nhlt.o obj-y += northbridge-uclass.o obj-$(CONFIG_I8259_PIC) += i8259.o obj-$(CONFIG_I8254_TIMER) += i8254.o diff --git a/arch/x86/lib/acpi_nhlt.c b/arch/x86/lib/acpi_nhlt.c new file mode 100644 index 0000000000..c64dd9c008 --- /dev/null +++ b/arch/x86/lib/acpi_nhlt.c @@ -0,0 +1,482 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2020 Google LLC + * + * Modified from coreboot nhlt.c + */ + +#define LOG_CATEGORY LOGC_ACPI + +#include <common.h> +#include <binman.h> +#include <dm.h> +#include <log.h> +#include <malloc.h> +#include <tables_csum.h> +#include <acpi/acpi_table.h> +#include <asm/acpi_nhlt.h> +#include <asm/unaligned.h> +#include <dm/acpi.h> + +#define NHLT_RID 1 +#define NHLT_SSID 1 +#define WAVEFORMAT_TAG 0xfffe +#define DEFAULT_VIRTUAL_BUS_ID 0 + +static const struct sub_format pcm_subformat = { + .data1 = 0x00000001, + .data2 = 0x0000, + .data3 = 0x0010, + .data4 = { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 }, +}; + +struct nhlt *nhlt_init(void) +{ + struct nhlt *nhlt; + + nhlt = malloc(sizeof(*nhlt)); + + if (!nhlt) + return NULL; + + memset(nhlt, 0, sizeof(*nhlt)); + nhlt->subsystem_id = NHLT_SSID; + + return nhlt; +} + +struct nhlt_endpoint *nhlt_add_endpoint(struct nhlt *nhlt, int link_type, + int device_type, int dir, + u16 vid, u16 did) +{ + struct nhlt_endpoint *endp; + + if (link_type < NHLT_LINK_HDA || link_type >= NHLT_MAX_LINK_TYPES) + return NULL; + + if (nhlt->num_endpoints >= MAX_ENDPOINTS) + return NULL; + + endp = &nhlt->endpoints[nhlt->num_endpoints]; + + endp->link_type = link_type; + endp->instance_id = nhlt->current_instance_id[link_type]; + endp->vendor_id = vid; + endp->device_id = did; + endp->revision_id = NHLT_RID; + endp->subsystem_id = nhlt->subsystem_id; + endp->device_type = device_type; + endp->direction = dir; + endp->virtual_bus_id = DEFAULT_VIRTUAL_BUS_ID; + + nhlt->num_endpoints++; + + return endp; +} + +static int append_specific_config(struct nhlt_specific_config *spec_cfg, + const void *config, size_t config_sz) +{ + size_t new_sz; + void *new_cfg; + + new_sz = spec_cfg->size + config_sz; + new_cfg = malloc(new_sz); + if (!new_cfg) + return -ENOMEM; + + /* Append new config */ + memcpy(new_cfg, spec_cfg->capabilities, spec_cfg->size); + memcpy(new_cfg + spec_cfg->size, config, config_sz); + + free(spec_cfg->capabilities); + + /* Update with new config data */ + spec_cfg->size = new_sz; + spec_cfg->capabilities = new_cfg; + + return 0; +} + +int nhlt_endpoint_append_config(struct nhlt_endpoint *endp, const void *config, + size_t config_sz) +{ + return append_specific_config(&endp->config, config, config_sz); +} + +struct nhlt_format *nhlt_add_format(struct nhlt_endpoint *endp, + int num_channels, int sample_freq_khz, + int container_bits_per_sample, + int valid_bits_per_sample, + uint32_t speaker_mask) +{ + struct nhlt_format *fmt; + struct nhlt_waveform *wave; + + if (endp->num_formats >= MAX_FORMATS) + return NULL; + + fmt = &endp->formats[endp->num_formats]; + wave = &fmt->waveform; + + wave->tag = WAVEFORMAT_TAG; + wave->num_channels = num_channels; + wave->samples_per_second = sample_freq_khz * 1000; + wave->bits_per_sample = container_bits_per_sample; + wave->extra_size = sizeof(wave->valid_bits_per_sample); + wave->extra_size += sizeof(wave->channel_mask); + wave->extra_size += sizeof(wave->sub_format); + wave->valid_bits_per_sample = valid_bits_per_sample; + wave->channel_mask = speaker_mask; + memcpy(&wave->sub_format, &pcm_subformat, sizeof(wave->sub_format)); + + /* Calculate the dervied fields */ + wave->block_align = wave->num_channels * wave->bits_per_sample / 8; + wave->bytes_per_second = wave->block_align * wave->samples_per_second; + + endp->num_formats++; + + return fmt; +} + +int nhlt_format_append_config(struct nhlt_format *fmt, const void *config, + size_t config_sz) +{ + return append_specific_config(&fmt->config, config, config_sz); +} + +int nhlt_endpoint_add_formats(struct nhlt_endpoint *endp, + const struct nhlt_format_config *formats, + size_t num_formats) +{ + ofnode node; + size_t i; + + node = binman_section_find_node("private-files"); + + for (i = 0; i < num_formats; i++) { + const struct nhlt_format_config *cfg = &formats[i]; + struct nhlt_format *fmt; + void *data; + int size; + int ret; + + fmt = nhlt_add_format(endp, cfg->num_channels, + cfg->sample_freq_khz, + cfg->container_bits_per_sample, + cfg->valid_bits_per_sample, + cfg->speaker_mask); + if (!fmt) + return -ENOSPC; + + if (!cfg->settings_file) + continue; + + ret = binman_entry_map(node, cfg->settings_file, &data, &size); + if (ret) { + log_warning("Failed to find settings file %s\n", + cfg->settings_file); + return log_msg_ret("settings", ret); + } + + ret = nhlt_format_append_config(fmt, data, size); + if (ret) + return log_msg_ret("append", ret); + } + + return 0; +} + +void nhlt_next_instance(struct nhlt *nhlt, int link_type) +{ + if (link_type < NHLT_LINK_HDA || link_type >= NHLT_MAX_LINK_TYPES) + return; + + nhlt->current_instance_id[link_type]++; +} + +static size_t calc_specific_config_size(struct nhlt_specific_config *cfg) +{ + return sizeof(cfg->size) + cfg->size; +} + +static size_t calc_format_size(struct nhlt_format *fmt) +{ + size_t sz = 0; + + /* Wave format first */ + sz += sizeof(fmt->waveform.tag); + sz += sizeof(fmt->waveform.num_channels); + sz += sizeof(fmt->waveform.samples_per_second); + sz += sizeof(fmt->waveform.bytes_per_second); + sz += sizeof(fmt->waveform.block_align); + sz += sizeof(fmt->waveform.bits_per_sample); + sz += sizeof(fmt->waveform.extra_size); + sz += sizeof(fmt->waveform.valid_bits_per_sample); + sz += sizeof(fmt->waveform.channel_mask); + sz += sizeof(fmt->waveform.sub_format); + + sz += calc_specific_config_size(&fmt->config); + + return sz; +} + +static size_t calc_endpoint_size(struct nhlt_endpoint *endp) +{ + int i; + size_t sz = 0; + + sz += sizeof(endp->length) + sizeof(endp->link_type); + sz += sizeof(endp->instance_id) + sizeof(endp->vendor_id); + sz += sizeof(endp->device_id) + sizeof(endp->revision_id); + sz += sizeof(endp->subsystem_id) + sizeof(endp->device_type); + sz += sizeof(endp->direction) + sizeof(endp->virtual_bus_id); + sz += calc_specific_config_size(&endp->config); + sz += sizeof(endp->num_formats); + + for (i = 0; i < endp->num_formats; i++) + sz += calc_format_size(&endp->formats[i]); + + /* Adjust endpoint length to reflect current configuration */ + endp->length = sz; + + return sz; +} + +static size_t calc_endpoints_size(struct nhlt *nhlt) +{ + size_t sz = 0; + int i; + + for (i = 0; i < nhlt->num_endpoints; i++) + sz += calc_endpoint_size(&nhlt->endpoints[i]); + + return sz; +} + +static size_t calc_size(struct nhlt *nhlt) +{ + return sizeof(nhlt->num_endpoints) + calc_endpoints_size(nhlt); +} + +size_t nhlt_current_size(struct nhlt *nhlt) +{ + return calc_size(nhlt) + sizeof(struct acpi_table_header); +} + +static void nhlt_free_resources(struct nhlt *nhlt) +{ + int i, j; + + /* Free all specific configs */ + for (i = 0; i < nhlt->num_endpoints; i++) { + struct nhlt_endpoint *endp = &nhlt->endpoints[i]; + + free(endp->config.capabilities); + for (j = 0; j < endp->num_formats; j++) { + struct nhlt_format *fmt = &endp->formats[j]; + + free(fmt->config.capabilities); + } + } + + /* Free nhlt object proper */ + free(nhlt); +} + +struct cursor { + u8 *buf; +}; + +static void ser8(struct cursor *cur, uint val) +{ + *cur->buf = val; + cur->buf += sizeof(val); +} + +static void ser16(struct cursor *cur, uint val) +{ + put_unaligned_le16(val, cur->buf); + cur->buf += sizeof(val); +} + +static void ser32(struct cursor *cur, uint val) +{ + put_unaligned_le32(val, cur->buf); + cur->buf += sizeof(val); +} + +static void serblob(struct cursor *cur, void *from, size_t sz) +{ + memcpy(cur->buf, from, sz); + cur->buf += sz; +} + +static void serialise_specific_config(struct nhlt_specific_config *cfg, + struct cursor *cur) +{ + ser32(cur, cfg->size); + serblob(cur, cfg->capabilities, cfg->size); +} + +static void serialise_waveform(struct nhlt_waveform *wave, struct cursor *cur) +{ + ser16(cur, wave->tag); + ser16(cur, wave->num_channels); + ser32(cur, wave->samples_per_second); + ser32(cur, wave->bytes_per_second); + ser16(cur, wave->block_align); + ser16(cur, wave->bits_per_sample); + ser16(cur, wave->extra_size); + ser16(cur, wave->valid_bits_per_sample); + ser32(cur, wave->channel_mask); + ser32(cur, wave->sub_format.data1); + ser16(cur, wave->sub_format.data2); + ser16(cur, wave->sub_format.data3); + serblob(cur, wave->sub_format.data4, sizeof(wave->sub_format.data4)); +} + +static void serialise_format(struct nhlt_format *fmt, struct cursor *cur) +{ + serialise_waveform(&fmt->waveform, cur); + serialise_specific_config(&fmt->config, cur); +} + +static void serialise_endpoint(struct nhlt_endpoint *endp, struct cursor *cur) +{ + int i; + + ser32(cur, endp->length); + ser8(cur, endp->link_type); + ser8(cur, endp->instance_id); + ser16(cur, endp->vendor_id); + ser16(cur, endp->device_id); + ser16(cur, endp->revision_id); + ser32(cur, endp->subsystem_id); + ser8(cur, endp->device_type); + ser8(cur, endp->direction); + ser8(cur, endp->virtual_bus_id); + serialise_specific_config(&endp->config, cur); + ser8(cur, endp->num_formats); + + for (i = 0; i < endp->num_formats; i++) + serialise_format(&endp->formats[i], cur); +} + +static void nhlt_serialise_endpoints(struct nhlt *nhlt, struct cursor *cur) +{ + int i; + + ser8(cur, nhlt->num_endpoints); + + for (i = 0; i < nhlt->num_endpoints; i++) + serialise_endpoint(&nhlt->endpoints[i], cur); +} + +int nhlt_serialise_oem_overrides(struct acpi_ctx *ctx, struct nhlt *nhlt, + const char *oem_id, const char *oem_table_id, + uint32_t oem_revision) +{ + struct cursor cur; + struct acpi_table_header *header; + size_t sz; + size_t oem_id_len; + size_t oem_table_id_len; + int ret; + + log_info("ACPI: * NHLT\n"); + sz = nhlt_current_size(nhlt); + + /* Create header */ + header = (void *)ctx->current; + memset(header, '\0', sizeof(struct acpi_table_header)); + acpi_fill_header(header, "NHLT"); + header->length = sz; + header->revision = acpi_get_table_revision(ACPITAB_NHLT); + + if (oem_id) { + oem_id_len = min((int)strlen(oem_id), 6); + memcpy(header->oem_id, oem_id, oem_id_len); + } + if (oem_table_id) { + oem_table_id_len = min((int)strlen(oem_table_id), 8); + memcpy(header->oem_table_id, oem_table_id, oem_table_id_len); + } + header->oem_revision = oem_revision; + + cur.buf = (void *)(header + 1); + nhlt_serialise_endpoints(nhlt, &cur); + + header->checksum = table_compute_checksum(header, sz); + nhlt_free_resources(nhlt); + + ret = acpi_add_table(ctx, ctx->current); + if (ret) + return log_msg_ret("add", ret); + acpi_inc_align(ctx, sz); + + return 0; +} + +static int _nhlt_add_single_endpoint(struct nhlt *nhlt, int virtual_bus_id, + const struct nhlt_endp_descriptor *epd) +{ + struct nhlt_endpoint *endp; + int ret; + + endp = nhlt_add_endpoint(nhlt, epd->link, epd->device, epd->direction, + epd->vid, epd->did); + if (!endp) + return -EINVAL; + + endp->virtual_bus_id = virtual_bus_id; + + ret = nhlt_endpoint_append_config(endp, epd->cfg, epd->cfg_size); + if (ret) + return ret; + + ret = nhlt_endpoint_add_formats(endp, epd->formats, epd->num_formats); + if (ret) + return log_msg_ret("formats", ret); + + return 0; +} + +static int _nhlt_add_endpoints(struct nhlt *nhlt, int virtual_bus_id, + const struct nhlt_endp_descriptor *epds, + size_t num_epds) +{ + size_t i; + int ret; + + for (i = 0; i < num_epds; i++) { + ret = _nhlt_add_single_endpoint(nhlt, virtual_bus_id, &epds[i]); + if (ret) + return log_ret(ret); + } + + return 0; +} + +int nhlt_add_endpoints(struct nhlt *nhlt, + const struct nhlt_endp_descriptor *epds, size_t num_epds) +{ + int ret; + + ret = _nhlt_add_endpoints(nhlt, DEFAULT_VIRTUAL_BUS_ID, epds, num_epds); + + return ret; +} + +int nhlt_add_ssp_endpoints(struct nhlt *nhlt, int virtual_bus_id, + const struct nhlt_endp_descriptor *epds, + size_t num_epds) +{ + int ret; + + ret = _nhlt_add_endpoints(nhlt, virtual_bus_id, epds, num_epds); + if (!ret) + nhlt_next_instance(nhlt, NHLT_LINK_SSP); + + return ret; +} diff --git a/arch/x86/lib/acpi_table.c b/arch/x86/lib/acpi_table.c index 6985ef4ba5..3a93fedfc3 100644 --- a/arch/x86/lib/acpi_table.c +++ b/arch/x86/lib/acpi_table.c @@ -14,6 +14,7 @@ #include <mapmem.h> #include <serial.h> #include <version.h> +#include <acpi/acpigen.h> #include <acpi/acpi_table.h> #include <asm/acpi/global_nvs.h> #include <asm/ioapic.h> @@ -22,6 +23,7 @@ #include <asm/tables.h> #include <asm/arch/global_nvs.h> #include <dm/acpi.h> +#include <linux/err.h> /* * IASL compiles the dsdt entries and writes the hex values @@ -153,7 +155,7 @@ static void acpi_create_madt(struct acpi_madt *madt) /* Fill out header fields */ acpi_fill_header(header, "APIC"); header->length = sizeof(struct acpi_madt); - header->revision = 4; + header->revision = ACPI_MADT_REV_ACPI_3_0; madt->lapic_addr = LAPIC_DEFAULT_BASE; madt->flags = ACPI_MADT_PCAT_COMPAT; @@ -210,13 +212,14 @@ static void acpi_create_mcfg(struct acpi_mcfg *mcfg) __weak u32 acpi_fill_csrt(u32 current) { - return current; + return 0; } -static void acpi_create_csrt(struct acpi_csrt *csrt) +static int acpi_create_csrt(struct acpi_csrt *csrt) { struct acpi_table_header *header = &(csrt->header); u32 current = (u32)csrt + sizeof(struct acpi_csrt); + uint ptr; memset((void *)csrt, 0, sizeof(struct acpi_csrt)); @@ -225,11 +228,16 @@ static void acpi_create_csrt(struct acpi_csrt *csrt) header->length = sizeof(struct acpi_csrt); header->revision = 0; - current = acpi_fill_csrt(current); + ptr = acpi_fill_csrt(current); + if (!ptr) + return -ENOENT; + current = ptr; /* (Re)calculate length and checksum */ header->length = current - (u32)csrt; header->checksum = table_compute_checksum((void *)csrt, header->length); + + return 0; } static void acpi_create_spcr(struct acpi_spcr *spcr) @@ -354,6 +362,25 @@ static void acpi_create_spcr(struct acpi_spcr *spcr) header->checksum = table_compute_checksum((void *)spcr, header->length); } +void acpi_create_ssdt(struct acpi_ctx *ctx, struct acpi_table_header *ssdt, + const char *oem_table_id) +{ + memset((void *)ssdt, '\0', sizeof(struct acpi_table_header)); + + acpi_fill_header(ssdt, "SSDT"); + ssdt->revision = acpi_get_table_revision(ACPITAB_SSDT); + ssdt->aslc_revision = 1; + ssdt->length = sizeof(struct acpi_table_header); + + acpi_inc(ctx, sizeof(struct acpi_table_header)); + + acpi_fill_ssdt(ctx); + + /* (Re)calculate length and checksum. */ + ssdt->length = ctx->current - (void *)ssdt; + ssdt->checksum = table_compute_checksum((void *)ssdt, ssdt->length); +} + /* * QEMU's version of write_acpi_tables is defined in drivers/misc/qfw.c */ @@ -363,6 +390,7 @@ ulong write_acpi_tables(ulong start_addr) struct acpi_facs *facs; struct acpi_table_header *dsdt; struct acpi_fadt *fadt; + struct acpi_table_header *ssdt; struct acpi_mcfg *mcfg; struct acpi_madt *madt; struct acpi_csrt *csrt; @@ -385,11 +413,20 @@ ulong write_acpi_tables(ulong start_addr) debug("ACPI: * DSDT\n"); dsdt = ctx->current; + + /* Put the table header first */ memcpy(dsdt, &AmlCode, sizeof(struct acpi_table_header)); acpi_inc(ctx, sizeof(struct acpi_table_header)); + + /* If the table is not empty, allow devices to inject things */ + if (dsdt->length >= sizeof(struct acpi_table_header)) + acpi_inject_dsdt(ctx); + + /* Copy in the AML code itself if any (after the header) */ memcpy(ctx->current, (char *)&AmlCode + sizeof(struct acpi_table_header), dsdt->length - sizeof(struct acpi_table_header)); + acpi_inc_align(ctx, dsdt->length - sizeof(struct acpi_table_header)); /* Pack GNVS into the ACPI table area */ @@ -404,12 +441,23 @@ ulong write_acpi_tables(ulong start_addr) } } - /* Update DSDT checksum since we patched the GNVS address */ + /* + * Recalculate the length and update the DSDT checksum since we patched + * the GNVS address. Set the checksum to zero since it is part of the + * region being checksummed. + */ + dsdt->length = ctx->current - (void *)dsdt; dsdt->checksum = 0; dsdt->checksum = table_compute_checksum((void *)dsdt, dsdt->length); - /* Fill in platform-specific global NVS variables */ - acpi_create_gnvs(ctx->current); + /* + * Fill in platform-specific global NVS variables. If this fails we + * cannot return the error but this should only happen while debugging. + */ + addr = acpi_create_gnvs(ctx->current); + if (IS_ERR_VALUE(addr)) + printf("Error: Failed to create GNVS\n"); + acpi_inc_align(ctx, sizeof(struct acpi_global_nvs)); debug("ACPI: * FADT\n"); @@ -418,11 +466,13 @@ ulong write_acpi_tables(ulong start_addr) acpi_create_fadt(fadt, facs, dsdt); acpi_add_table(ctx, fadt); - debug("ACPI: * MADT\n"); - madt = ctx->current; - acpi_create_madt(madt); - acpi_inc_align(ctx, madt->header.length); - acpi_add_table(ctx, madt); + debug("ACPI: * SSDT\n"); + ssdt = (struct acpi_table_header *)ctx->current; + acpi_create_ssdt(ctx, ssdt, OEM_TABLE_ID); + if (ssdt->length > sizeof(struct acpi_table_header)) { + acpi_inc_align(ctx, ssdt->length); + acpi_add_table(ctx, ssdt); + } debug("ACPI: * MCFG\n"); mcfg = ctx->current; @@ -430,11 +480,18 @@ ulong write_acpi_tables(ulong start_addr) acpi_inc_align(ctx, mcfg->header.length); acpi_add_table(ctx, mcfg); + debug("ACPI: * MADT\n"); + madt = ctx->current; + acpi_create_madt(madt); + acpi_inc_align(ctx, madt->header.length); + acpi_add_table(ctx, madt); + debug("ACPI: * CSRT\n"); csrt = ctx->current; - acpi_create_csrt(csrt); - acpi_inc_align(ctx, csrt->header.length); - acpi_add_table(ctx, csrt); + if (!acpi_create_csrt(csrt)) { + acpi_inc_align(ctx, csrt->header.length); + acpi_add_table(ctx, csrt); + } debug("ACPI: * SPCR\n"); spcr = ctx->current; diff --git a/arch/x86/lib/coreboot_table.c b/arch/x86/lib/coreboot_table.c index 331c1b7e5a..6cd3244301 100644 --- a/arch/x86/lib/coreboot_table.c +++ b/arch/x86/lib/coreboot_table.c @@ -21,11 +21,11 @@ int high_table_reserve(void) gd->arch.high_table_ptr = gd->start_addr_sp; /* clear the memory */ -#ifdef CONFIG_HAVE_ACPI_RESUME - if (gd->arch.prev_sleep_state != ACPI_S3) -#endif + if (IS_ENABLED(CONFIG_HAVE_ACPI_RESUME) && + gd->arch.prev_sleep_state != ACPI_S3) { memset((void *)gd->arch.high_table_ptr, 0, CONFIG_HIGH_TABLE_SIZE); + } gd->start_addr_sp &= ~0xf; diff --git a/arch/x86/lib/fsp/fsp_common.c b/arch/x86/lib/fsp/fsp_common.c index cf32b3e512..ea52954725 100644 --- a/arch/x86/lib/fsp/fsp_common.c +++ b/arch/x86/lib/fsp/fsp_common.c @@ -47,7 +47,7 @@ int fsp_init_phase_pci(void) return status ? -EPERM : 0; } -void board_final_cleanup(void) +void board_final_init(void) { u32 status; @@ -60,7 +60,6 @@ void board_final_cleanup(void) debug("OK\n"); } -#ifdef CONFIG_HAVE_ACPI_RESUME int fsp_save_s3_stack(void) { struct udevice *dev; @@ -84,4 +83,3 @@ int fsp_save_s3_stack(void) return 0; } -#endif diff --git a/arch/x86/lib/fsp/fsp_dram.c b/arch/x86/lib/fsp/fsp_dram.c index ad5a0f79ad..01d498c21e 100644 --- a/arch/x86/lib/fsp/fsp_dram.c +++ b/arch/x86/lib/fsp/fsp_dram.c @@ -117,17 +117,21 @@ unsigned int install_e820_map(unsigned int max_entries, entries[num_entries].type = E820_RESERVED; num_entries++; -#ifdef CONFIG_HAVE_ACPI_RESUME - /* - * Everything between U-Boot's stack and ram top needs to be - * reserved in order for ACPI S3 resume to work. - */ - entries[num_entries].addr = gd->start_addr_sp - CONFIG_STACK_SIZE; - entries[num_entries].size = gd->ram_top - gd->start_addr_sp + - CONFIG_STACK_SIZE; - entries[num_entries].type = E820_RESERVED; - num_entries++; -#endif + if (IS_ENABLED(CONFIG_HAVE_ACPI_RESUME)) { + ulong stack_size; + + stack_size = CONFIG_IS_ENABLED(HAVE_ACPI_RESUME, + (CONFIG_STACK_SIZE), (0)); + /* + * Everything between U-Boot's stack and ram top needs to be + * reserved in order for ACPI S3 resume to work. + */ + entries[num_entries].addr = gd->start_addr_sp - stack_size; + entries[num_entries].size = gd->ram_top - gd->start_addr_sp + + stack_size; + entries[num_entries].type = E820_RESERVED; + num_entries++; + } return num_entries; } diff --git a/arch/x86/lib/fsp1/fsp_common.c b/arch/x86/lib/fsp1/fsp_common.c index 43d32b7abe..da351cf097 100644 --- a/arch/x86/lib/fsp1/fsp_common.c +++ b/arch/x86/lib/fsp1/fsp_common.c @@ -46,10 +46,12 @@ int arch_fsp_init(void) void *nvs; int stack = CONFIG_FSP_TEMP_RAM_ADDR; int boot_mode = BOOT_FULL_CONFIG; -#ifdef CONFIG_HAVE_ACPI_RESUME - int prev_sleep_state = chipset_prev_sleep_state(); - gd->arch.prev_sleep_state = prev_sleep_state; -#endif + int prev_sleep_state; + + if (IS_ENABLED(CONFIG_HAVE_ACPI_RESUME)) { + prev_sleep_state = chipset_prev_sleep_state(); + gd->arch.prev_sleep_state = prev_sleep_state; + } if (!gd->arch.hob_list) { if (IS_ENABLED(CONFIG_ENABLE_MRC_CACHE)) @@ -57,8 +59,8 @@ int arch_fsp_init(void) else nvs = NULL; -#ifdef CONFIG_HAVE_ACPI_RESUME - if (prev_sleep_state == ACPI_S3) { + if (IS_ENABLED(CONFIG_HAVE_ACPI_RESUME) && + prev_sleep_state == ACPI_S3) { if (nvs == NULL) { /* If waking from S3 and no cache then */ debug("No MRC cache found in S3 resume path\n"); @@ -79,7 +81,7 @@ int arch_fsp_init(void) stack = cmos_read32(CMOS_FSP_STACK_ADDR); boot_mode = BOOT_ON_S3_RESUME; } -#endif + /* * The first time we enter here, call fsp_init(). * Note the execution does not return to this function, diff --git a/arch/x86/lib/fsp2/fsp_dram.c b/arch/x86/lib/fsp2/fsp_dram.c index 1c82b81831..c9f6402e6a 100644 --- a/arch/x86/lib/fsp2/fsp_dram.c +++ b/arch/x86/lib/fsp2/fsp_dram.c @@ -27,11 +27,10 @@ int dram_init(void) return 0; } if (spl_phase() == PHASE_SPL) { -#ifdef CONFIG_HAVE_ACPI_RESUME - bool s3wake = gd->arch.prev_sleep_state == ACPI_S3; -#else bool s3wake = false; -#endif + + s3wake = IS_ENABLED(CONFIG_HAVE_ACPI_RESUME) && + gd->arch.prev_sleep_state == ACPI_S3; ret = fsp_memory_init(s3wake, IS_ENABLED(CONFIG_APL_BOOT_FROM_FAST_SPI_FLASH)); diff --git a/arch/x86/lib/fsp2/fsp_meminit.c b/arch/x86/lib/fsp2/fsp_meminit.c index faf9c29aef..ce0b0aff76 100644 --- a/arch/x86/lib/fsp2/fsp_meminit.c +++ b/arch/x86/lib/fsp2/fsp_meminit.c @@ -9,6 +9,7 @@ #include <common.h> #include <binman.h> #include <bootstage.h> +#include <dm.h> #include <log.h> #include <asm/mrccache.h> #include <asm/fsp/fsp_infoheader.h> @@ -63,8 +64,10 @@ int fsp_memory_init(bool s3wake, bool use_spi_flash) struct fsp_header *hdr; struct hob_header *hob; struct udevice *dev; + int delay; int ret; + log_debug("Locating FSP\n"); ret = fsp_locate_fsp(FSP_M, &entry, use_spi_flash, &dev, &hdr, NULL); if (ret) return log_msg_ret("locate FSP", ret); @@ -76,21 +79,32 @@ int fsp_memory_init(bool s3wake, bool use_spi_flash) return log_msg_ret("Bad UPD signature", -EPERM); memcpy(&upd, fsp_upd, sizeof(upd)); + delay = dev_read_u32_default(dev, "fspm,training-delay", 0); ret = fspm_update_config(dev, &upd); - if (ret) - return log_msg_ret("Could not setup config", ret); - - debug("SDRAM init..."); + if (ret) { + if (ret != -ENOENT) + return log_msg_ret("Could not setup config", ret); + } else { + delay = 0; + } + + if (delay) + printf("SDRAM training (%d seconds)...", delay); + else + log_debug("SDRAM init..."); bootstage_start(BOOTSTAGE_ID_ACCUM_FSP_M, "fsp-m"); func = (fsp_memory_init_func)(hdr->img_base + hdr->fsp_mem_init); ret = func(&upd, &hob); bootstage_accum(BOOTSTAGE_ID_ACCUM_FSP_M); cpu_reinit_fpu(); + if (delay) + printf("done\n"); + else + log_debug("done\n"); if (ret) return log_msg_ret("SDRAM init fail\n", ret); gd->arch.hob_list = hob; - debug("done\n"); ret = fspm_done(dev); if (ret) diff --git a/arch/x86/lib/fsp2/fsp_silicon_init.c b/arch/x86/lib/fsp2/fsp_silicon_init.c index 45c0c7d90b..0f221a864f 100644 --- a/arch/x86/lib/fsp2/fsp_silicon_init.c +++ b/arch/x86/lib/fsp2/fsp_silicon_init.c @@ -32,6 +32,7 @@ int fsp_silicon_init(bool s3wake, bool use_spi_flash) &rom_offset); if (ret) return log_msg_ret("locate FSP", ret); + binman_set_rom_offset(rom_offset); gd->arch.fsp_s_hdr = hdr; /* Copy over the default config */ diff --git a/arch/x86/lib/tables.c b/arch/x86/lib/tables.c index 574d331d76..7bad5dd303 100644 --- a/arch/x86/lib/tables.c +++ b/arch/x86/lib/tables.c @@ -4,6 +4,7 @@ */ #include <common.h> +#include <log.h> #include <malloc.h> #include <smbios.h> #include <acpi/acpi_table.h> @@ -20,21 +21,32 @@ */ typedef ulong (*table_write)(ulong addr); -static table_write table_write_funcs[] = { +/** + * struct table_info - Information about each table to write + * + * @name: Name of table (for debugging) + * @write: Function to call to write this table + */ +struct table_info { + const char *name; + table_write write; +}; + +static struct table_info table_list[] = { #ifdef CONFIG_GENERATE_PIRQ_TABLE - write_pirq_routing_table, + { "pirq", write_pirq_routing_table }, #endif #ifdef CONFIG_GENERATE_SFI_TABLE - write_sfi_table, + { "sfi", write_sfi_table, }, #endif #ifdef CONFIG_GENERATE_MP_TABLE - write_mp_table, + { "mp", write_mp_table, }, #endif #ifdef CONFIG_GENERATE_ACPI_TABLE - write_acpi_tables, + { "acpi", write_acpi_tables, }, #endif #ifdef CONFIG_GENERATE_SMBIOS_TABLE - write_smbios_table, + { "smbios", write_smbios_table, }, #endif }; @@ -58,19 +70,22 @@ void write_tables(void) u32 rom_table_end; #ifdef CONFIG_SEABIOS u32 high_table, table_size; - struct memory_area cfg_tables[ARRAY_SIZE(table_write_funcs) + 1]; + struct memory_area cfg_tables[ARRAY_SIZE(table_list) + 1]; #endif int i; - for (i = 0; i < ARRAY_SIZE(table_write_funcs); i++) { - rom_table_end = table_write_funcs[i](rom_table_start); + debug("Writing tables to %x:\n", rom_table_start); + for (i = 0; i < ARRAY_SIZE(table_list); i++) { + const struct table_info *table = &table_list[i]; + + rom_table_end = table->write(rom_table_start); rom_table_end = ALIGN(rom_table_end, ROM_TABLE_ALIGN); #ifdef CONFIG_SEABIOS table_size = rom_table_end - rom_table_start; high_table = (u32)high_table_malloc(table_size); if (high_table) { - table_write_funcs[i](high_table); + table->write(high_table); cfg_tables[i].start = high_table; cfg_tables[i].size = table_size; @@ -79,6 +94,8 @@ void write_tables(void) } #endif + debug("- wrote '%s' to %x, end %x\n", table->name, + rom_table_start, rom_table_end); rom_table_start = rom_table_end; } @@ -87,4 +104,5 @@ void write_tables(void) cfg_tables[i].size = 0; write_coreboot_table(CB_TABLE_ADDR, cfg_tables); #endif + debug("- done writing tables\n"); } diff --git a/arch/x86/lib/zimage.c b/arch/x86/lib/zimage.c index 64d14e8911..d2b6002008 100644 --- a/arch/x86/lib/zimage.c +++ b/arch/x86/lib/zimage.c @@ -304,13 +304,6 @@ int setup_zimage(struct boot_params *setup_base, char *cmd_line, int auto_boot, return 0; } -void setup_pcat_compatibility(void) - __attribute__((weak, alias("__setup_pcat_compatibility"))); - -void __setup_pcat_compatibility(void) -{ -} - int do_zboot(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { struct boot_params *base_ptr; @@ -323,9 +316,6 @@ int do_zboot(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) disable_interrupts(); - /* Setup board for maximum PC/AT Compatibility */ - setup_pcat_compatibility(); - if (argc >= 2) { /* argv[1] holds the address of the bzImage */ s = argv[1]; |