diff options
author | Stefan Reinauer <stefan.reinauer@coreboot.org> | 2015-07-13 09:39:15 +0200 |
---|---|---|
committer | Stefan Reinauer <stefan.reinauer@coreboot.org> | 2015-07-13 21:04:56 +0200 |
commit | 6cb3a59fd5e754c3627b79db21c5bcc284bfd721 (patch) | |
tree | e83db5b11ee4a29d496dcf2798d024b6b8455ab7 /src/arch/x86/boot | |
parent | 9693885ad88d21ead7bd9ebc32f3e4901841b18b (diff) |
x86: flatten hierarchy
It never made sense to have bootblock_* in init, but
pirq_routing.c in boot, and some ld scripts on the main
level while others live in subdirectories.
This patch flattens the directory hierarchy and makes
x86 more similar to the other architectures.
Change-Id: I4056038fe7813e4d3d3042c441e7ab6076a36384
Signed-off-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
Reviewed-on: http://review.coreboot.org/10901
Tested-by: build bot (Jenkins)
Tested-by: Raptor Engineering Automated Test Stand <noreply@raptorengineeringinc.com>
Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
Diffstat (limited to 'src/arch/x86/boot')
-rw-r--r-- | src/arch/x86/boot/Makefile.inc | 22 | ||||
-rw-r--r-- | src/arch/x86/boot/acpi.c | 1137 | ||||
-rw-r--r-- | src/arch/x86/boot/acpigen.c | 728 | ||||
-rw-r--r-- | src/arch/x86/boot/boot.c | 210 | ||||
-rw-r--r-- | src/arch/x86/boot/cbmem.c | 76 | ||||
-rw-r--r-- | src/arch/x86/boot/gdt.c | 62 | ||||
-rw-r--r-- | src/arch/x86/boot/mpspec.c | 597 | ||||
-rw-r--r-- | src/arch/x86/boot/pirq_routing.c | 208 | ||||
-rw-r--r-- | src/arch/x86/boot/smbios.c | 581 | ||||
-rw-r--r-- | src/arch/x86/boot/tables.c | 221 | ||||
-rw-r--r-- | src/arch/x86/boot/wakeup.S | 99 |
11 files changed, 0 insertions, 3941 deletions
diff --git a/src/arch/x86/boot/Makefile.inc b/src/arch/x86/boot/Makefile.inc deleted file mode 100644 index 10a1efd242..0000000000 --- a/src/arch/x86/boot/Makefile.inc +++ /dev/null @@ -1,22 +0,0 @@ - -ifeq ($(CONFIG_ARCH_ROMSTAGE_X86_32)$(CONFIG_ARCH_ROMSTAGE_X86_64),y) - -romstage-y += cbmem.c -romstage-y += boot.c - -endif # CONFIG_ARCH_ROMSTAGE_X86_32 / CONFIG_ARCH_ROMSTAGE_X86_64 - -ifeq ($(CONFIG_ARCH_RAMSTAGE_X86_32)$(CONFIG_ARCH_RAMSTAGE_X86_64),y) - -ramstage-y += boot.c -ramstage-y += gdt.c -ramstage-y += tables.c -ramstage-y += cbmem.c -ramstage-$(CONFIG_GENERATE_MP_TABLE) += mpspec.c -ramstage-$(CONFIG_GENERATE_PIRQ_TABLE) += pirq_routing.c -ramstage-$(CONFIG_HAVE_ACPI_TABLES) += acpi.c -ramstage-$(CONFIG_GENERATE_SMBIOS_TABLES) += smbios.c -ramstage-$(CONFIG_HAVE_ACPI_TABLES) += acpigen.c -ramstage-$(CONFIG_HAVE_ACPI_RESUME) += wakeup.S - -endif # CONFIG_ARCH_RAMSTAGE_X86_32 / CONFIG_ARCH_RAMSTAGE_X86_64 diff --git a/src/arch/x86/boot/acpi.c b/src/arch/x86/boot/acpi.c deleted file mode 100644 index 134e43782e..0000000000 --- a/src/arch/x86/boot/acpi.c +++ /dev/null @@ -1,1137 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * coreboot ACPI Table support - * written by Stefan Reinauer <stepan@openbios.org> - * - * Copyright (C) 2004 SUSE LINUX AG - * Copyright (C) 2005-2009 coresystems GmbH - * - * ACPI FADT, FACS, and DSDT table support added by - * Nick Barker <nick.barker9@btinternet.com>, and those portions - * Copyright (C) 2004 Nick Barker - * - * Copyright (C) 2005 ADVANCED MICRO DEVICES, INC. All Rights Reserved. - * 2005.9 yhlu add SRAT table generation - */ - -/* - * Each system port implementing ACPI has to provide two functions: - * - * write_acpi_tables() - * acpi_dump_apics() - * - * See Kontron 986LCD-M port for a good example of an ACPI implementation - * in coreboot. - */ - -#include <console/console.h> -#include <string.h> -#include <arch/acpi.h> -#include <arch/acpigen.h> -#include <device/pci.h> -#include <cbmem.h> -#include <cpu/x86/lapic_def.h> -#include <cpu/cpu.h> -#include <cbfs.h> -#include <timestamp.h> -#include <romstage_handoff.h> - -/* FIXME: Kconfig doesn't support overridable defaults :-( */ -#ifndef CONFIG_HPET_MIN_TICKS -#define CONFIG_HPET_MIN_TICKS 0x1000 -#endif - -u8 acpi_checksum(u8 *table, u32 length) -{ - u8 ret = 0; - while (length--) { - ret += *table; - table++; - } - return -ret; -} - -/** - * Add an ACPI table to the RSDT (and XSDT) structure, recalculate length - * and checksum. - */ -void acpi_add_table(acpi_rsdp_t *rsdp, void *table) -{ - int i, entries_num; - acpi_rsdt_t *rsdt; - acpi_xsdt_t *xsdt = NULL; - - /* The RSDT is mandatory... */ - rsdt = (acpi_rsdt_t *)(uintptr_t)rsdp->rsdt_address; - - /* ...while the XSDT is not. */ - if (rsdp->xsdt_address) - xsdt = (acpi_xsdt_t *)((uintptr_t)rsdp->xsdt_address); - - /* This should always be MAX_ACPI_TABLES. */ - entries_num = ARRAY_SIZE(rsdt->entry); - - for (i = 0; i < entries_num; i++) { - if (rsdt->entry[i] == 0) - break; - } - - if (i >= entries_num) { - printk(BIOS_ERR, "ACPI: Error: Could not add ACPI table, " - "too many tables.\n"); - return; - } - - /* Add table to the RSDT. */ - rsdt->entry[i] = (uintptr_t)table; - - /* Fix RSDT length or the kernel will assume invalid entries. */ - rsdt->header.length = sizeof(acpi_header_t) + (sizeof(u32) * (i + 1)); - - /* Re-calculate checksum. */ - rsdt->header.checksum = 0; /* Hope this won't get optimized away */ - rsdt->header.checksum = acpi_checksum((u8 *)rsdt, rsdt->header.length); - - /* - * And now the same thing for the XSDT. We use the same index as for - * now we want the XSDT and RSDT to always be in sync in coreboot. - */ - if (xsdt) { - /* Add table to the XSDT. */ - xsdt->entry[i] = (u64)(uintptr_t)table; - - /* Fix XSDT length. */ - xsdt->header.length = sizeof(acpi_header_t) + - (sizeof(u64) * (i + 1)); - - /* Re-calculate checksum. */ - xsdt->header.checksum = 0; - xsdt->header.checksum = acpi_checksum((u8 *)xsdt, - xsdt->header.length); - } - - printk(BIOS_DEBUG, "ACPI: added table %d/%d, length now %d\n", - i + 1, entries_num, rsdt->header.length); -} - -int acpi_create_mcfg_mmconfig(acpi_mcfg_mmconfig_t *mmconfig, u32 base, - u16 seg_nr, u8 start, u8 end) -{ - memset(mmconfig, 0, sizeof(*mmconfig)); - mmconfig->base_address = base; - mmconfig->base_reserved = 0; - mmconfig->pci_segment_group_number = seg_nr; - mmconfig->start_bus_number = start; - mmconfig->end_bus_number = end; - - return sizeof(acpi_mcfg_mmconfig_t); -} - -int acpi_create_madt_lapic(acpi_madt_lapic_t *lapic, u8 cpu, u8 apic) -{ - lapic->type = 0; /* Local APIC structure */ - lapic->length = sizeof(acpi_madt_lapic_t); - lapic->flags = (1 << 0); /* Processor/LAPIC enabled */ - lapic->processor_id = cpu; - lapic->apic_id = apic; - - return lapic->length; -} - -unsigned long acpi_create_madt_lapics(unsigned long current) -{ - struct device *cpu; - int index = 0; - - for (cpu = all_devices; cpu; cpu = cpu->next) { - if ((cpu->path.type != DEVICE_PATH_APIC) || - (cpu->bus->dev->path.type != DEVICE_PATH_CPU_CLUSTER)) { - continue; - } - if (!cpu->enabled) - continue; - current += acpi_create_madt_lapic((acpi_madt_lapic_t *)current, - index, cpu->path.apic.apic_id); - index++; - } - - return current; -} - -int acpi_create_madt_ioapic(acpi_madt_ioapic_t *ioapic, u8 id, u32 addr, - u32 gsi_base) -{ - ioapic->type = 1; /* I/O APIC structure */ - ioapic->length = sizeof(acpi_madt_ioapic_t); - ioapic->reserved = 0x00; - ioapic->gsi_base = gsi_base; - ioapic->ioapic_id = id; - ioapic->ioapic_addr = addr; - - return ioapic->length; -} - -int acpi_create_madt_irqoverride(acpi_madt_irqoverride_t *irqoverride, - u8 bus, u8 source, u32 gsirq, u16 flags) -{ - irqoverride->type = 2; /* Interrupt source override */ - irqoverride->length = sizeof(acpi_madt_irqoverride_t); - irqoverride->bus = bus; - irqoverride->source = source; - irqoverride->gsirq = gsirq; - irqoverride->flags = flags; - - return irqoverride->length; -} - -int acpi_create_madt_lapic_nmi(acpi_madt_lapic_nmi_t *lapic_nmi, u8 cpu, - u16 flags, u8 lint) -{ - lapic_nmi->type = 4; /* Local APIC NMI structure */ - lapic_nmi->length = sizeof(acpi_madt_lapic_nmi_t); - lapic_nmi->flags = flags; - lapic_nmi->processor_id = cpu; - lapic_nmi->lint = lint; - - return lapic_nmi->length; -} - -void acpi_create_madt(acpi_madt_t *madt) -{ - acpi_header_t *header = &(madt->header); - unsigned long current = (unsigned long)madt + sizeof(acpi_madt_t); - - memset((void *)madt, 0, sizeof(acpi_madt_t)); - - /* Fill out header fields. */ - memcpy(header->signature, "APIC", 4); - memcpy(header->oem_id, OEM_ID, 6); - memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8); - memcpy(header->asl_compiler_id, ASLC, 4); - - header->length = sizeof(acpi_madt_t); - header->revision = 1; /* ACPI 1.0/2.0: 1, ACPI 3.0: 2, ACPI 4.0: 3 */ - - madt->lapic_addr = LOCAL_APIC_ADDR; - madt->flags = 0x1; /* PCAT_COMPAT */ - - current = acpi_fill_madt(current); - - /* (Re)calculate length and checksum. */ - header->length = current - (unsigned long)madt; - - header->checksum = acpi_checksum((void *)madt, header->length); -} - -/* MCFG is defined in the PCI Firmware Specification 3.0. */ -void acpi_create_mcfg(acpi_mcfg_t *mcfg) -{ - acpi_header_t *header = &(mcfg->header); - unsigned long current = (unsigned long)mcfg + sizeof(acpi_mcfg_t); - - memset((void *)mcfg, 0, sizeof(acpi_mcfg_t)); - - /* Fill out header fields. */ - memcpy(header->signature, "MCFG", 4); - memcpy(header->oem_id, OEM_ID, 6); - memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8); - memcpy(header->asl_compiler_id, ASLC, 4); - - header->length = sizeof(acpi_mcfg_t); - header->revision = 1; - - current = acpi_fill_mcfg(current); - - /* (Re)calculate length and checksum. */ - header->length = current - (unsigned long)mcfg; - header->checksum = acpi_checksum((void *)mcfg, header->length); -} - -static void *get_tcpa_log(u32 *size) -{ - const struct cbmem_entry *ce; - const u32 tcpa_default_log_len = 0x10000; - void *lasa; - ce = cbmem_entry_find(CBMEM_ID_TCPA_LOG); - if (ce) { - lasa = cbmem_entry_start(ce); - *size = cbmem_entry_size(ce); - printk(BIOS_DEBUG, "TCPA log found at %p\n", lasa); - return lasa; - } - lasa = cbmem_add(CBMEM_ID_TCPA_LOG, tcpa_default_log_len); - if (!lasa) { - printk(BIOS_ERR, "TCPA log creation failed\n"); - return NULL; - } - - printk(BIOS_DEBUG, "TCPA log created at %p\n", lasa); - memset (lasa, 0, tcpa_default_log_len); - - *size = tcpa_default_log_len; - return lasa; -} - -static void acpi_create_tcpa(acpi_tcpa_t *tcpa) -{ - acpi_header_t *header = &(tcpa->header); - u32 tcpa_log_len; - void *lasa; - - memset((void *)tcpa, 0, sizeof(acpi_tcpa_t)); - - lasa = get_tcpa_log(&tcpa_log_len); - if (!lasa) { - return; - } - - /* Fill out header fields. */ - memcpy(header->signature, "TCPA", 4); - memcpy(header->oem_id, OEM_ID, 6); - memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8); - memcpy(header->asl_compiler_id, ASLC, 4); - - header->length = sizeof(acpi_tcpa_t); - header->revision = 2; - - tcpa->platform_class = 0; - tcpa->laml = tcpa_log_len; - tcpa->lasa = (uintptr_t) lasa; - - /* Calculate checksum. */ - header->checksum = acpi_checksum((void *)tcpa, header->length); -} - -void acpi_create_ssdt_generator(acpi_header_t *ssdt, const char *oem_table_id) -{ - unsigned long current = (unsigned long)ssdt + sizeof(acpi_header_t); - - memset((void *)ssdt, 0, sizeof(acpi_header_t)); - - memcpy(&ssdt->signature, "SSDT", 4); - ssdt->revision = 2; /* ACPI 1.0/2.0: ?, ACPI 3.0/4.0: 2 */ - memcpy(&ssdt->oem_id, OEM_ID, 6); - memcpy(&ssdt->oem_table_id, oem_table_id, 8); - ssdt->oem_revision = 42; - memcpy(&ssdt->asl_compiler_id, ASLC, 4); - ssdt->asl_compiler_revision = 42; - ssdt->length = sizeof(acpi_header_t); - - acpigen_set_current((char *) current); - { - struct device *dev; - for (dev = all_devices; dev; dev = dev->next) - if (dev->ops && dev->ops->acpi_fill_ssdt_generator) { - dev->ops->acpi_fill_ssdt_generator(dev); - } - current = (unsigned long) acpigen_get_current(); - } - - /* (Re)calculate length and checksum. */ - ssdt->length = current - (unsigned long)ssdt; - ssdt->checksum = acpi_checksum((void *)ssdt, ssdt->length); -} - -int acpi_create_srat_lapic(acpi_srat_lapic_t *lapic, u8 node, u8 apic) -{ - memset((void *)lapic, 0, sizeof(acpi_srat_lapic_t)); - - lapic->type = 0; /* Processor local APIC/SAPIC affinity structure */ - lapic->length = sizeof(acpi_srat_lapic_t); - lapic->flags = (1 << 0); /* Enabled (the use of this structure). */ - lapic->proximity_domain_7_0 = node; - /* TODO: proximity_domain_31_8, local SAPIC EID, clock domain. */ - lapic->apic_id = apic; - - return lapic->length; -} - -int acpi_create_srat_mem(acpi_srat_mem_t *mem, u8 node, u32 basek, u32 sizek, - u32 flags) -{ - mem->type = 1; /* Memory affinity structure */ - mem->length = sizeof(acpi_srat_mem_t); - mem->base_address_low = (basek << 10); - mem->base_address_high = (basek >> (32 - 10)); - mem->length_low = (sizek << 10); - mem->length_high = (sizek >> (32 - 10)); - mem->proximity_domain = node; - mem->flags = flags; - - return mem->length; -} - -/* http://www.microsoft.com/whdc/system/sysinternals/sratdwn.mspx */ -void acpi_create_srat(acpi_srat_t *srat, - unsigned long (*acpi_fill_srat)(unsigned long current)) -{ - acpi_header_t *header = &(srat->header); - unsigned long current = (unsigned long)srat + sizeof(acpi_srat_t); - - memset((void *)srat, 0, sizeof(acpi_srat_t)); - - /* Fill out header fields. */ - memcpy(header->signature, "SRAT", 4); - memcpy(header->oem_id, OEM_ID, 6); - memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8); - memcpy(header->asl_compiler_id, ASLC, 4); - - header->length = sizeof(acpi_srat_t); - header->revision = 1; /* ACPI 1.0: N/A, 2.0: 1, 3.0: 2, 4.0: 3 */ - - srat->resv = 1; /* Spec: Reserved to 1 for backwards compatibility. */ - - current = acpi_fill_srat(current); - - /* (Re)calculate length and checksum. */ - header->length = current - (unsigned long)srat; - header->checksum = acpi_checksum((void *)srat, header->length); -} - -void acpi_create_dmar(acpi_dmar_t *dmar, - unsigned long (*acpi_fill_dmar) (unsigned long)) -{ - acpi_header_t *header = &(dmar->header); - unsigned long current = (unsigned long)dmar + sizeof(acpi_dmar_t); - - memset((void *)dmar, 0, sizeof(acpi_dmar_t)); - - /* Fill out header fields. */ - memcpy(header->signature, "DMAR", 4); - memcpy(header->oem_id, OEM_ID, 6); - memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8); - memcpy(header->asl_compiler_id, ASLC, 4); - - header->length = sizeof(acpi_dmar_t); - header->revision = 1; - - dmar->host_address_width = 40 - 1; /* FIXME: == MTRR size? */ - dmar->flags = 0; - - current = acpi_fill_dmar(current); - - /* (Re)calculate length and checksum. */ - header->length = current - (unsigned long)dmar; - header->checksum = acpi_checksum((void *)dmar, header->length); -} - -unsigned long acpi_create_dmar_drhd(unsigned long current, u8 flags, - u16 segment, u32 bar) -{ - dmar_entry_t *drhd = (dmar_entry_t *)current; - memset(drhd, 0, sizeof(*drhd)); - drhd->type = DMAR_DRHD; - drhd->length = sizeof(*drhd); /* will be fixed up later */ - drhd->flags = flags; - drhd->segment = segment; - drhd->bar = bar; - - return drhd->length; -} - -void acpi_dmar_drhd_fixup(unsigned long base, unsigned long current) -{ - dmar_entry_t *drhd = (dmar_entry_t *)base; - drhd->length = current - base; -} - -unsigned long acpi_create_dmar_drhd_ds_pci(unsigned long current, u8 segment, - u8 dev, u8 fn) -{ - dev_scope_t *ds = (dev_scope_t *)current; - memset(ds, 0, sizeof(*ds)); - ds->type = SCOPE_PCI_ENDPOINT; - ds->length = sizeof(*ds) + 2; /* we don't support longer paths yet */ - ds->start_bus = segment; - ds->path[0].dev = dev; - ds->path[0].fn = fn; - - return ds->length; -} - -/* http://h21007.www2.hp.com/portal/download/files/unprot/Itanium/slit.pdf */ -void acpi_create_slit(acpi_slit_t *slit, - unsigned long (*acpi_fill_slit)(unsigned long current)) -{ - acpi_header_t *header = &(slit->header); - unsigned long current = (unsigned long)slit + sizeof(acpi_slit_t); - - memset((void *)slit, 0, sizeof(acpi_slit_t)); - - /* Fill out header fields. */ - memcpy(header->signature, "SLIT", 4); - memcpy(header->oem_id, OEM_ID, 6); - memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8); - memcpy(header->asl_compiler_id, ASLC, 4); - - header->length = sizeof(acpi_slit_t); - header->revision = 1; /* ACPI 1.0: N/A, ACPI 2.0/3.0/4.0: 1 */ - - current = acpi_fill_slit(current); - - /* (Re)calculate length and checksum. */ - header->length = current - (unsigned long)slit; - header->checksum = acpi_checksum((void *)slit, header->length); -} - -/* http://www.intel.com/hardwaredesign/hpetspec_1.pdf */ -void acpi_create_hpet(acpi_hpet_t *hpet) -{ - acpi_header_t *header = &(hpet->header); - acpi_addr_t *addr = &(hpet->addr); - - memset((void *)hpet, 0, sizeof(acpi_hpet_t)); - - /* Fill out header fields. */ - memcpy(header->signature, "HPET", 4); - memcpy(header->oem_id, OEM_ID, 6); - memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8); - memcpy(header->asl_compiler_id, ASLC, 4); - - header->length = sizeof(acpi_hpet_t); - header->revision = 1; /* Currently 1. Table added in ACPI 2.0. */ - - /* Fill out HPET address. */ - addr->space_id = 0; /* Memory */ - addr->bit_width = 64; - addr->bit_offset = 0; - addr->addrl = CONFIG_HPET_ADDRESS & 0xffffffff; - addr->addrh = ((unsigned long long)CONFIG_HPET_ADDRESS) >> 32; - - hpet->id = *(unsigned int*)CONFIG_HPET_ADDRESS; - hpet->number = 0; - hpet->min_tick = CONFIG_HPET_MIN_TICKS; - - header->checksum = acpi_checksum((void *)hpet, sizeof(acpi_hpet_t)); -} - -unsigned long acpi_write_hpet(device_t device, unsigned long current, acpi_rsdp_t *rsdp) -{ - acpi_hpet_t *hpet; - - /* - * We explicitly add these tables later on: - */ - printk(BIOS_DEBUG, "ACPI: * HPET\n"); - - hpet = (acpi_hpet_t *) current; - current += sizeof(acpi_hpet_t); - current = ALIGN(current, 16); - acpi_create_hpet(hpet); - acpi_add_table(rsdp, hpet); - - return current; -} - -void acpi_create_facs(acpi_facs_t *facs) -{ - memset((void *)facs, 0, sizeof(acpi_facs_t)); - - memcpy(facs->signature, "FACS", 4); - facs->length = sizeof(acpi_facs_t); - facs->hardware_signature = 0; - facs->firmware_waking_vector = 0; - facs->global_lock = 0; - facs->flags = 0; - facs->x_firmware_waking_vector_l = 0; - facs->x_firmware_waking_vector_h = 0; - facs->version = 1; /* ACPI 1.0: 0, ACPI 2.0/3.0: 1, ACPI 4.0: 2 */ -} - -static void acpi_write_rsdt(acpi_rsdt_t *rsdt, char *oem_id, char *oem_table_id) -{ - acpi_header_t *header = &(rsdt->header); - - /* Fill out header fields. */ - memcpy(header->signature, "RSDT", 4); - memcpy(header->oem_id, oem_id, 6); - memcpy(header->oem_table_id, oem_table_id, 8); - memcpy(header->asl_compiler_id, ASLC, 4); - - header->length = sizeof(acpi_rsdt_t); - header->revision = 1; /* ACPI 1.0/2.0/3.0/4.0: 1 */ - - /* Entries are filled in later, we come with an empty set. */ - - /* Fix checksum. */ - header->checksum = acpi_checksum((void *)rsdt, sizeof(acpi_rsdt_t)); -} - -static void acpi_write_xsdt(acpi_xsdt_t *xsdt, char *oem_id, char *oem_table_id) -{ - acpi_header_t *header = &(xsdt->header); - - /* Fill out header fields. */ - memcpy(header->signature, "XSDT", 4); - memcpy(header->oem_id, oem_id, 6); - memcpy(header->oem_table_id, oem_table_id, 8); - memcpy(header->asl_compiler_id, ASLC, 4); - - header->length = sizeof(acpi_xsdt_t); - header->revision = 1; /* ACPI 1.0: N/A, 2.0/3.0/4.0: 1 */ - - /* Entries are filled in later, we come with an empty set. */ - - /* Fix checksum. */ - header->checksum = acpi_checksum((void *)xsdt, sizeof(acpi_xsdt_t)); -} - -static void acpi_write_rsdp(acpi_rsdp_t *rsdp, acpi_rsdt_t *rsdt, - acpi_xsdt_t *xsdt, char *oem_id) -{ - memset(rsdp, 0, sizeof(acpi_rsdp_t)); - - memcpy(rsdp->signature, RSDP_SIG, 8); - memcpy(rsdp->oem_id, oem_id, 6); - - rsdp->length = sizeof(acpi_rsdp_t); - rsdp->rsdt_address = (uintptr_t)rsdt; - - /* - * Revision: ACPI 1.0: 0, ACPI 2.0/3.0/4.0: 2. - * - * Some OSes expect an XSDT to be present for RSD PTR revisions >= 2. - * If we don't have an ACPI XSDT, force ACPI 1.0 (and thus RSD PTR - * revision 0). - */ - if (xsdt == NULL) { - rsdp->revision = 0; - } else { - rsdp->xsdt_address = (u64)(uintptr_t)xsdt; - rsdp->revision = 2; - } - - /* Calculate checksums. */ - rsdp->checksum = acpi_checksum((void *)rsdp, 20); - rsdp->ext_checksum = acpi_checksum((void *)rsdp, sizeof(acpi_rsdp_t)); -} - -unsigned long acpi_create_hest_error_source(acpi_hest_t *hest, acpi_hest_esd_t *esd, u16 type, void *data, u16 data_len) -{ - acpi_header_t *header = &(hest->header); - acpi_hest_hen_t *hen; - void *pos; - u16 len; - - pos = esd; - memset(pos, 0, sizeof(acpi_hest_esd_t)); - len = 0; - esd->type = type; /* MCE */ - esd->source_id = hest->error_source_count; - esd->flags = 0; /* FIRMWARE_FIRST */ - esd->enabled = 1; - esd->prealloc_erecords = 1; - esd->max_section_per_record = 0x1; - - len += sizeof(acpi_hest_esd_t); - pos = esd + 1; - - switch (type) { - case 0: /* MCE */ - break; - case 1: /* CMC */ - hen = (acpi_hest_hen_t *) (pos); - memset(pos, 0, sizeof(acpi_hest_hen_t)); - hen->type = 3; /* SCI? */ - hen->length = sizeof(acpi_hest_hen_t); - hen->conf_we = 0; /* Configuration Write Enable. */ - hen->poll_interval = 0; - hen->vector = 0; - hen->sw2poll_threshold_val = 0; - hen->sw2poll_threshold_win = 0; - hen->error_threshold_val = 0; - hen->error_threshold_win = 0; - len += sizeof(acpi_hest_hen_t); - pos = hen + 1; - break; - case 2: /* NMI */ - case 6: /* AER Root Port */ - case 7: /* AER Endpoint */ - case 8: /* AER Bridge */ - case 9: /* Generic Hardware Error Source. */ - /* TODO: */ - break; - default: - printk(BIOS_DEBUG, "Invalid type of Error Source."); - break; - } - hest->error_source_count ++; - - memcpy(pos, data, data_len); - len += data_len; - header->length += len; - - return len; -} - -/* ACPI 4.0 */ -void acpi_write_hest(acpi_hest_t *hest, - unsigned long (*acpi_fill_hest)(acpi_hest_t *hest)) -{ - acpi_header_t *header = &(hest->header); - - memset(hest, 0, sizeof(acpi_hest_t)); - - memcpy(header->signature, "HEST", 4); - memcpy(header->oem_id, OEM_ID, 6); - memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8); - memcpy(header->asl_compiler_id, ASLC, 4); - header->length += sizeof(acpi_hest_t); - header->revision = 1; - - acpi_fill_hest(hest); - - /* Calculate checksums. */ - header->checksum = acpi_checksum((void *)hest, header->length); -} - -#if IS_ENABLED(CONFIG_COMMON_FADT) -void acpi_create_fadt(acpi_fadt_t *fadt,acpi_facs_t *facs, void *dsdt) -{ - acpi_header_t *header = &(fadt->header); - - memset((void *) fadt, 0, sizeof(acpi_fadt_t)); - memcpy(header->signature, "FACP", 4); - header->length = sizeof(acpi_fadt_t); - header->revision = 4; - memcpy(header->oem_id, OEM_ID, 6); - memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8); - memcpy(header->asl_compiler_id, ASLC, 4); - header->asl_compiler_revision = 0; - - fadt->firmware_ctrl = (unsigned long) facs; - fadt->dsdt = (unsigned long) dsdt; - - fadt->x_firmware_ctl_l = (unsigned long)facs; - fadt->x_firmware_ctl_h = 0; - fadt->x_dsdt_l = (unsigned long)dsdt; - fadt->x_dsdt_h = 0; - - if(IS_ENABLED(CONFIG_SYSTEM_TYPE_LAPTOP)) { - fadt->preferred_pm_profile = PM_MOBILE; - } else { - fadt->preferred_pm_profile = PM_DESKTOP; - } - - acpi_fill_fadt(fadt); - - header->checksum = - acpi_checksum((void *) fadt, header->length); -} -#endif - -unsigned long __attribute__ ((weak)) fw_cfg_acpi_tables(unsigned long start) -{ - return 0; -} - -#define ALIGN_CURRENT current = (ALIGN(current, 16)) -unsigned long write_acpi_tables(unsigned long start) -{ - unsigned long current; - acpi_rsdp_t *rsdp; - acpi_rsdt_t *rsdt; - acpi_xsdt_t *xsdt; - acpi_fadt_t *fadt; - acpi_facs_t *facs; - acpi_header_t *slic_file, *slic; - acpi_header_t *ssdt; - acpi_header_t *dsdt_file, *dsdt; - acpi_mcfg_t *mcfg; - acpi_tcpa_t *tcpa; - acpi_madt_t *madt; - struct device *dev; - unsigned long fw; - size_t slic_size, dsdt_size; - char oem_id[6], oem_table_id[8]; - - current = start; - - /* Align ACPI tables to 16byte */ - ALIGN_CURRENT; - - fw = fw_cfg_acpi_tables(current); - if (fw) - return fw; - -#if CONFIG_COMPILE_IN_DSDT - extern char _binary_dsdt_aml_start; - extern char _binary_dsdt_aml_end; - dsdt_file = (acpi_header_t *)&_binary_dsdt_aml_start; - dsdt_size = (size_t)(&_binary_dsdt_aml_end - &_binary_dsdt_aml_start); -#else - dsdt_file = cbfs_boot_map_with_leak( - CONFIG_CBFS_PREFIX "/dsdt.aml", - CBFS_TYPE_RAW, &dsdt_size); -#endif - if (!dsdt_file) { - printk(BIOS_ERR, "No DSDT file, skipping ACPI tables\n"); - return current; - } - - if (dsdt_file->length > dsdt_size - || dsdt_file->length < sizeof (acpi_header_t) - || memcmp(dsdt_file->signature, "DSDT", 4) != 0) { - printk(BIOS_ERR, "Invalid DSDT file, skipping ACPI tables\n"); - return current; - } - - slic_file = cbfs_boot_map_with_leak(CONFIG_CBFS_PREFIX "/slic", - CBFS_TYPE_RAW, &slic_size); - if (slic_file - && (slic_file->length > slic_size - || slic_file->length < sizeof (acpi_header_t) - || memcmp(slic_file->signature, "SLIC", 4) != 0)) { - slic_file = 0; - } - - if (slic_file) { - memcpy(oem_id, slic_file->oem_id, 6); - memcpy(oem_table_id, slic_file->oem_table_id, 8); - } else { - memcpy(oem_id, OEM_ID, 6); - memcpy(oem_table_id, ACPI_TABLE_CREATOR, 8); - } - - printk(BIOS_INFO, "ACPI: Writing ACPI tables at %lx.\n", start); - - /* We need at least an RSDP and an RSDT Table */ - rsdp = (acpi_rsdp_t *) current; - current += sizeof(acpi_rsdp_t); - ALIGN_CURRENT; - rsdt = (acpi_rsdt_t *) current; - current += sizeof(acpi_rsdt_t); - ALIGN_CURRENT; - xsdt = (acpi_xsdt_t *) current; - current += sizeof(acpi_xsdt_t); - ALIGN_CURRENT; - - /* clear all table memory */ - memset((void *) start, 0, current - start); - - acpi_write_rsdp(rsdp, rsdt, xsdt, oem_id); - acpi_write_rsdt(rsdt, oem_id, oem_table_id); - acpi_write_xsdt(xsdt, oem_id, oem_table_id); - - printk(BIOS_DEBUG, "ACPI: * FACS\n"); - facs = (acpi_facs_t *) current; - current += sizeof(acpi_facs_t); - ALIGN_CURRENT; - acpi_create_facs(facs); - - printk(BIOS_DEBUG, "ACPI: * DSDT\n"); - dsdt = (acpi_header_t *) current; - memcpy(dsdt, dsdt_file, sizeof(acpi_header_t)); - if (dsdt->length >= sizeof(acpi_header_t)) { - current += sizeof(acpi_header_t); - - acpigen_set_current((char *) current); - for (dev = all_devices; dev; dev = dev->next) - if (dev->ops && dev->ops->acpi_inject_dsdt_generator) { - dev->ops->acpi_inject_dsdt_generator(dev); - } - current = (unsigned long) acpigen_get_current(); - memcpy((char *)current, - (char *)dsdt_file + sizeof(acpi_header_t), - dsdt->length - sizeof(acpi_header_t)); - current += dsdt->length - sizeof(acpi_header_t); - - /* (Re)calculate length and checksum. */ - dsdt->length = current - (unsigned long)dsdt; - dsdt->checksum = 0; - dsdt->checksum = acpi_checksum((void *)dsdt, dsdt->length); - } - - ALIGN_CURRENT; - - printk(BIOS_DEBUG, "ACPI: * FADT\n"); - fadt = (acpi_fadt_t *) current; - current += sizeof(acpi_fadt_t); - ALIGN_CURRENT; - - acpi_create_fadt(fadt, facs, dsdt); - acpi_add_table(rsdp, fadt); - - if (slic_file) { - printk(BIOS_DEBUG, "ACPI: * SLIC\n"); - slic = (acpi_header_t *)current; - memcpy(slic, slic_file, slic_file->length); - current += slic_file->length; - ALIGN_CURRENT; - acpi_add_table(rsdp, slic); - } - - printk(BIOS_DEBUG, "ACPI: * SSDT\n"); - ssdt = (acpi_header_t *)current; - acpi_create_ssdt_generator(ssdt, ACPI_TABLE_CREATOR); - if (ssdt->length > sizeof(acpi_header_t)) { - current += ssdt->length; - acpi_add_table(rsdp, ssdt); - ALIGN_CURRENT; - } - - printk(BIOS_DEBUG, "ACPI: * MCFG\n"); - mcfg = (acpi_mcfg_t *) current; - acpi_create_mcfg(mcfg); - if (mcfg->header.length > sizeof(acpi_mcfg_t)) { - current += mcfg->header.length; - ALIGN_CURRENT; - acpi_add_table(rsdp, mcfg); - } - - printk(BIOS_DEBUG, "ACPI: * TCPA\n"); - tcpa = (acpi_tcpa_t *) current; - acpi_create_tcpa(tcpa); - if (tcpa->header.length >= sizeof(acpi_tcpa_t)) { - current += tcpa->header.length; - ALIGN_CURRENT; - acpi_add_table(rsdp, tcpa); - } - - printk(BIOS_DEBUG, "ACPI: * MADT\n"); - - madt = (acpi_madt_t *) current; - acpi_create_madt(madt); - if (madt->header.length > sizeof(acpi_madt_t)) { - current+=madt->header.length; - acpi_add_table(rsdp,madt); - } - ALIGN_CURRENT; - - printk(BIOS_DEBUG, "current = %lx\n", current); - - for (dev = all_devices; dev; dev = dev->next) { - if (dev->ops && dev->ops->write_acpi_tables) { - current = dev->ops->write_acpi_tables(dev, current, rsdp); - ALIGN_CURRENT; - } - } - - printk(BIOS_INFO, "ACPI: done.\n"); - return current; -} - -#if CONFIG_HAVE_ACPI_RESUME -void __attribute__((weak)) mainboard_suspend_resume(void) -{ -} - -void acpi_resume(void *wake_vec) -{ -#if CONFIG_HAVE_SMI_HANDLER - u32 *gnvs_address = cbmem_find(CBMEM_ID_ACPI_GNVS_PTR); - - /* Restore GNVS pointer in SMM if found */ - if (gnvs_address && *gnvs_address) { - printk(BIOS_DEBUG, "Restore GNVS pointer to 0x%08x\n", - *gnvs_address); - smm_setup_structures((void *)*gnvs_address, NULL, NULL); - } -#endif - - /* Call mainboard resume handler first, if defined. */ - mainboard_suspend_resume(); - - post_code(POST_OS_RESUME); - acpi_jump_to_wakeup(wake_vec); -} - -/* This is filled with acpi_is_wakeup() call early in ramstage. */ -int acpi_slp_type = -1; - -#if IS_ENABLED(CONFIG_EARLY_CBMEM_INIT) -int acpi_get_sleep_type(void) -{ - struct romstage_handoff *handoff; - - handoff = cbmem_find(CBMEM_ID_ROMSTAGE_INFO); - - if (handoff == NULL) { - printk(BIOS_DEBUG, "Unknown boot method, assuming normal.\n"); - return 0; - } else if (handoff->s3_resume) { - printk(BIOS_DEBUG, "S3 Resume.\n"); - return 3; - } else { - printk(BIOS_DEBUG, "Normal boot.\n"); - return 0; - } -} -#endif - -static void acpi_handoff_wakeup(void) -{ - if (acpi_slp_type < 0) - acpi_slp_type = acpi_get_sleep_type(); -} - -int acpi_is_wakeup(void) -{ - acpi_handoff_wakeup(); - /* Both resume from S2 and resume from S3 restart at CPU reset */ - return (acpi_slp_type == 3 || acpi_slp_type == 2); -} - -int acpi_is_wakeup_s3(void) -{ - acpi_handoff_wakeup(); - return (acpi_slp_type == 3); -} - -void acpi_fail_wakeup(void) -{ - if (acpi_slp_type == 3 || acpi_slp_type == 2) - acpi_slp_type = 0; -} - -void acpi_prepare_resume_backup(void) -{ - if (!acpi_s3_resume_allowed()) - return; - - /* Let's prepare the ACPI S3 Resume area now already, so we can rely on - * it being there during reboot time. We don't need the pointer, nor - * the result right now. If it fails, ACPI resume will be disabled. - */ - - if (HIGH_MEMORY_SAVE) - cbmem_add(CBMEM_ID_RESUME, HIGH_MEMORY_SAVE); -} - -static acpi_rsdp_t *valid_rsdp(acpi_rsdp_t *rsdp) -{ - if (strncmp((char *)rsdp, RSDP_SIG, sizeof(RSDP_SIG) - 1) != 0) - return NULL; - - printk(BIOS_DEBUG, "Looking on %p for valid checksum\n", rsdp); - - if (acpi_checksum((void *)rsdp, 20) != 0) - return NULL; - printk(BIOS_DEBUG, "Checksum 1 passed\n"); - - if ((rsdp->revision > 1) && (acpi_checksum((void *)rsdp, - rsdp->length) != 0)) - return NULL; - printk(BIOS_DEBUG, "Checksum 2 passed all OK\n"); - - return rsdp; -} - -static acpi_rsdp_t *rsdp; - -void *acpi_get_wakeup_rsdp(void) -{ - return rsdp; -} - -void *acpi_find_wakeup_vector(void) -{ - char *p, *end; - acpi_rsdt_t *rsdt; - acpi_facs_t *facs; - acpi_fadt_t *fadt = NULL; - void *wake_vec; - int i; - - rsdp = NULL; - - if (!acpi_is_wakeup()) - return NULL; - - printk(BIOS_DEBUG, "Trying to find the wakeup vector...\n"); - - /* Find RSDP. */ - for (p = (char *)0xe0000; p < (char *)0xfffff; p += 16) { - if ((rsdp = valid_rsdp((acpi_rsdp_t *)p))) - break; - } - - if (rsdp == NULL) - return NULL; - - printk(BIOS_DEBUG, "RSDP found at %p\n", rsdp); - rsdt = (acpi_rsdt_t *) rsdp->rsdt_address; - - end = (char *)rsdt + rsdt->header.length; - printk(BIOS_DEBUG, "RSDT found at %p ends at %p\n", rsdt, end); - - for (i = 0; ((char *)&rsdt->entry[i]) < end; i++) { - fadt = (acpi_fadt_t *)rsdt->entry[i]; - if (strncmp((char *)fadt, "FACP", 4) == 0) - break; - fadt = NULL; - } - - if (fadt == NULL) - return NULL; - - printk(BIOS_DEBUG, "FADT found at %p\n", fadt); - facs = (acpi_facs_t *)fadt->firmware_ctrl; - - if (facs == NULL) { - printk(BIOS_DEBUG, "No FACS found, wake up from S3 not " - "possible.\n"); - return NULL; - } - - printk(BIOS_DEBUG, "FACS found at %p\n", facs); - wake_vec = (void *)facs->firmware_waking_vector; - printk(BIOS_DEBUG, "OS waking vector is %p\n", wake_vec); - - return wake_vec; -} - -#if CONFIG_SMP -extern char *lowmem_backup; -extern char *lowmem_backup_ptr; -extern int lowmem_backup_size; -#endif - -#define WAKEUP_BASE 0x600 - -void (*acpi_do_wakeup)(u32 vector, u32 backup_source, u32 backup_target, - u32 backup_size) asmlinkage = (void *)WAKEUP_BASE; - -extern unsigned char __wakeup; -extern unsigned int __wakeup_size; - -void acpi_jump_to_wakeup(void *vector) -{ - u32 acpi_backup_memory = 0; - - if (HIGH_MEMORY_SAVE && acpi_s3_resume_allowed()) { - acpi_backup_memory = (u32)cbmem_find(CBMEM_ID_RESUME); - - if (!acpi_backup_memory) { - printk(BIOS_WARNING, "ACPI: Backup memory missing. " - "No S3 resume.\n"); - return; - } - } - -#if CONFIG_SMP - // FIXME: This should go into the ACPI backup memory, too. No pork sausages. - /* - * Just restore the SMP trampoline and continue with wakeup on - * assembly level. - */ - memcpy(lowmem_backup_ptr, lowmem_backup, lowmem_backup_size); -#endif - - /* Copy wakeup trampoline in place. */ - memcpy((void *)WAKEUP_BASE, &__wakeup, __wakeup_size); - - timestamp_add_now(TS_ACPI_WAKE_JUMP); - - acpi_do_wakeup((u32)vector, acpi_backup_memory, CONFIG_RAMBASE, - HIGH_MEMORY_SAVE); -} -#endif - -void acpi_save_gnvs(u32 gnvs_address) -{ - u32 *gnvs = cbmem_add(CBMEM_ID_ACPI_GNVS_PTR, sizeof(*gnvs)); - if (gnvs) - *gnvs = gnvs_address; -} diff --git a/src/arch/x86/boot/acpigen.c b/src/arch/x86/boot/acpigen.c deleted file mode 100644 index 3aa823c363..0000000000 --- a/src/arch/x86/boot/acpigen.c +++ /dev/null @@ -1,728 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2009 Rudolf Marek <r.marek@assembler.cz> - * - * 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. - */ - -/* How much nesting do we support? */ -#define ACPIGEN_LENSTACK_SIZE 10 - -/* - * If you need to change this, change acpigen_write_f and - * acpigen_pop_len - */ - -#define ACPIGEN_MAXLEN 0xfff - -#include <string.h> -#include <arch/acpigen.h> -#include <console/console.h> -#include <device/device.h> - -static char *gencurrent; - -char *len_stack[ACPIGEN_LENSTACK_SIZE]; -int ltop = 0; - -void acpigen_write_len_f(void) -{ - ASSERT(ltop < (ACPIGEN_LENSTACK_SIZE - 1)) - len_stack[ltop++] = gencurrent; - acpigen_emit_byte(0); - acpigen_emit_byte(0); -} - -void acpigen_pop_len(void) -{ - int len; - ASSERT(ltop > 0) - char *p = len_stack[--ltop]; - len = gencurrent - p; - ASSERT(len <= ACPIGEN_MAXLEN) - /* generate store length for 0xfff max */ - p[0] = (0x40 | (len & 0xf)); - p[1] = (len >> 4 & 0xff); - -} - -void acpigen_set_current(char *curr) -{ - gencurrent = curr; -} - -char *acpigen_get_current(void) -{ - return gencurrent; -} - -void acpigen_emit_byte(unsigned char b) -{ - (*gencurrent++) = b; -} - -void acpigen_write_package(int nr_el) -{ - /* package op */ - acpigen_emit_byte(0x12); - acpigen_write_len_f(); - acpigen_emit_byte(nr_el); -} - -void acpigen_write_byte(unsigned int data) -{ - /* byte op */ - acpigen_emit_byte(0xa); - acpigen_emit_byte(data & 0xff); -} - -void acpigen_write_dword(unsigned int data) -{ - /* dword op */ - acpigen_emit_byte(0xc); - acpigen_emit_byte(data & 0xff); - acpigen_emit_byte((data >> 8) & 0xff); - acpigen_emit_byte((data >> 16) & 0xff); - acpigen_emit_byte((data >> 24) & 0xff); -} - -void acpigen_write_qword(uint64_t data) -{ - /* qword op */ - acpigen_emit_byte(0xe); - acpigen_emit_byte(data & 0xff); - acpigen_emit_byte((data >> 8) & 0xff); - acpigen_emit_byte((data >> 16) & 0xff); - acpigen_emit_byte((data >> 24) & 0xff); - acpigen_emit_byte((data >> 32) & 0xff); - acpigen_emit_byte((data >> 40) & 0xff); - acpigen_emit_byte((data >> 48) & 0xff); - acpigen_emit_byte((data >> 56) & 0xff); -} - -void acpigen_write_name_byte(const char *name, uint8_t val) -{ - acpigen_write_name(name); - acpigen_write_byte(val); -} - -void acpigen_write_name_dword(const char *name, uint32_t val) -{ - acpigen_write_name(name); - acpigen_write_dword(val); -} - -void acpigen_write_name_qword(const char *name, uint64_t val) -{ - acpigen_write_name(name); - acpigen_write_qword(val); -} - -void acpigen_emit_stream(const char *data, int size) -{ - int i; - for (i = 0; i < size; i++) { - acpigen_emit_byte(data[i]); - } -} - -/* - * The naming conventions for ACPI namespace names are a bit tricky as - * each element has to be 4 chars wide (»All names are a fixed 32 bits.«) - * and »By convention, when an ASL compiler pads a name shorter than 4 - * characters, it is done so with trailing underscores (‘_’).«. - * - * Check sections 5.3, 18.2.2 and 18.4 of ACPI spec 3.0 for details. - */ - -static void acpigen_emit_simple_namestring(const char *name) { - int i; - char ud[] = "____"; - for (i = 0; i < 4; i++) { - if ((name[i] == '\0') || (name[i] == '.')) { - acpigen_emit_stream(ud, 4 - i); - break; - } else { - acpigen_emit_byte(name[i]); - } - } -} - -static void acpigen_emit_double_namestring(const char *name, int dotpos) { - /* mark dual name prefix */ - acpigen_emit_byte(0x2e); - acpigen_emit_simple_namestring(name); - acpigen_emit_simple_namestring(&name[dotpos + 1]); -} - -static void acpigen_emit_multi_namestring(const char *name) { - int count = 0; - unsigned char *pathlen; - /* mark multi name prefix */ - acpigen_emit_byte(0x2f); - acpigen_emit_byte(0x0); - pathlen = ((unsigned char *) acpigen_get_current()) - 1; - - while (name[0] != '\0') { - acpigen_emit_simple_namestring(name); - /* find end or next entity */ - while ((name[0] != '.') && (name[0] != '\0')) - name++; - /* forward to next */ - if (name[0] == '.') - name++; - count++; - } - - pathlen[0] = count; -} - - -void acpigen_emit_namestring(const char *namepath) { - int dotcount = 0, i; - int dotpos = 0; - - /* We can start with a '\'. */ - if (namepath[0] == '\\') { - acpigen_emit_byte('\\'); - namepath++; - } - - /* And there can be any number of '^' */ - while (namepath[0] == '^') { - acpigen_emit_byte('^'); - namepath++; - } - - /* If we have only \\ or only ^...^. Then we need to put a null - name (0x00). */ - if(namepath[0] == '\0') { - acpigen_emit_byte(0x00); - return; - } - - i = 0; - while (namepath[i] != '\0') { - if (namepath[i] == '.') { - dotcount++; - dotpos = i; - } - i++; - } - - if (dotcount == 0) { - acpigen_emit_simple_namestring(namepath); - } else if (dotcount == 1) { - acpigen_emit_double_namestring(namepath, dotpos); - } else { - acpigen_emit_multi_namestring(namepath); - } -} - -void acpigen_write_name(const char *name) -{ - /* name op */ - acpigen_emit_byte(0x8); - acpigen_emit_namestring(name); -} - -void acpigen_write_scope(const char *name) -{ - /* scope op */ - acpigen_emit_byte(0x10); - acpigen_write_len_f(); - acpigen_emit_namestring(name); -} - -void acpigen_write_processor(u8 cpuindex, u32 pblock_addr, u8 pblock_len) -{ -/* - Processor (\_PR.CPUcpuindex, cpuindex, pblock_addr, pblock_len) - { -*/ - char pscope[16]; - /* processor op */ - acpigen_emit_byte(0x5b); - acpigen_emit_byte(0x83); - acpigen_write_len_f(); - - snprintf(pscope, sizeof (pscope), - "\\_PR.CP%02d", (unsigned int) cpuindex); - acpigen_emit_namestring(pscope); - acpigen_emit_byte(cpuindex); - acpigen_emit_byte(pblock_addr & 0xff); - acpigen_emit_byte((pblock_addr >> 8) & 0xff); - acpigen_emit_byte((pblock_addr >> 16) & 0xff); - acpigen_emit_byte((pblock_addr >> 24) & 0xff); - acpigen_emit_byte(pblock_len); -} - -void acpigen_write_empty_PCT(void) -{ -/* - Name (_PCT, Package (0x02) - { - ResourceTemplate () - { - Register (FFixedHW, - 0x00, // Bit Width - 0x00, // Bit Offset - 0x0000000000000000, // Address - ,) - }, - - ResourceTemplate () - { - Register (FFixedHW, - 0x00, // Bit Width - 0x00, // Bit Offset - 0x0000000000000000, // Address - ,) - } - }) -*/ - static char stream[] = { - 0x08, 0x5F, 0x50, 0x43, 0x54, 0x12, 0x2C, /* 00000030 "0._PCT.," */ - 0x02, 0x11, 0x14, 0x0A, 0x11, 0x82, 0x0C, 0x00, /* 00000038 "........" */ - 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 00000040 "........" */ - 0x00, 0x00, 0x00, 0x00, 0x79, 0x00, 0x11, 0x14, /* 00000048 "....y..." */ - 0x0A, 0x11, 0x82, 0x0C, 0x00, 0x7F, 0x00, 0x00, /* 00000050 "........" */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 00000058 "........" */ - 0x00, 0x79, 0x00 - }; - acpigen_emit_stream(stream, ARRAY_SIZE(stream)); -} - -void acpigen_write_empty_PTC(void) -{ -/* - Name (_PTC, Package (0x02) - { - ResourceTemplate () - { - Register (FFixedHW, - 0x00, // Bit Width - 0x00, // Bit Offset - 0x0000000000000000, // Address - ,) - }, - - ResourceTemplate () - { - Register (FFixedHW, - 0x00, // Bit Width - 0x00, // Bit Offset - 0x0000000000000000, // Address - ,) - } - }) -*/ - acpi_addr_t addr = { - .space_id = ACPI_ADDRESS_SPACE_FIXED, - .bit_width = 0, - .bit_offset = 0, - { - .resv = 0 - }, - .addrl = 0, - .addrh = 0, - }; - - acpigen_write_name("_PTC"); - acpigen_write_package(2); - - /* ControlRegister */ - acpigen_write_resourcetemplate_header(); - acpigen_write_register(&addr); - acpigen_write_resourcetemplate_footer(); - - /* StatusRegister */ - acpigen_write_resourcetemplate_header(); - acpigen_write_register(&addr); - acpigen_write_resourcetemplate_footer(); - - acpigen_pop_len(); -} - -void acpigen_write_method(const char *name, int nargs) -{ - /* method op */ - acpigen_emit_byte(0x14); - acpigen_write_len_f(); - acpigen_emit_namestring(name); - acpigen_emit_byte(nargs & 7); -} - -void acpigen_write_device(const char *name) -{ - /* method op */ - acpigen_emit_byte(0x5b); - acpigen_emit_byte(0x82); - acpigen_write_len_f(); - acpigen_emit_namestring(name); -} - -/* - * Generates a func with max supported P-states. - */ -void acpigen_write_PPC(u8 nr) -{ -/* - Method (_PPC, 0, NotSerialized) - { - Return (nr) - } -*/ - acpigen_write_method("_PPC", 0); - /* return */ - acpigen_emit_byte(0xa4); - /* arg */ - acpigen_write_byte(nr); - acpigen_pop_len(); -} - -/* - * Generates a func with max supported P-states saved - * in the variable PPCM. - */ -void acpigen_write_PPC_NVS(void) -{ -/* - Method (_PPC, 0, NotSerialized) - { - Return (PPCM) - } -*/ - acpigen_write_method("_PPC", 0); - /* return */ - acpigen_emit_byte(0xa4); - /* arg */ - acpigen_emit_namestring("PPCM"); - acpigen_pop_len(); -} - -void acpigen_write_TPC(const char *gnvs_tpc_limit) -{ -/* - // Sample _TPC method - Method (_TPC, 0, NotSerialized) - { - Return (\TLVL) - } - */ - acpigen_write_method("_TPC", 0); - acpigen_emit_byte(0xa4); /* ReturnOp */ - acpigen_emit_namestring(gnvs_tpc_limit); - acpigen_pop_len(); -} - -void acpigen_write_PSS_package(u32 coreFreq, u32 power, u32 transLat, - u32 busmLat, u32 control, u32 status) -{ - acpigen_write_package(6); - acpigen_write_dword(coreFreq); - acpigen_write_dword(power); - acpigen_write_dword(transLat); - acpigen_write_dword(busmLat); - acpigen_write_dword(control); - acpigen_write_dword(status); - acpigen_pop_len(); - - printk(BIOS_DEBUG, "PSS: %uMHz power %u control 0x%x status 0x%x\n", - coreFreq, power, control, status); -} - -void acpigen_write_PSD_package(u32 domain, u32 numprocs, PSD_coord coordtype) -{ - acpigen_write_name("_PSD"); - acpigen_write_package(1); - acpigen_write_package(5); - acpigen_write_byte(5); // 5 values - acpigen_write_byte(0); // revision 0 - acpigen_write_dword(domain); - acpigen_write_dword(coordtype); - acpigen_write_dword(numprocs); - acpigen_pop_len(); - acpigen_pop_len(); -} - -void acpigen_write_CST_package_entry(acpi_cstate_t *cstate) -{ - acpigen_write_package(4); - acpigen_write_resourcetemplate_header(); - acpigen_write_register(&cstate->resource); - acpigen_write_resourcetemplate_footer(); - acpigen_write_dword(cstate->ctype); - acpigen_write_dword(cstate->latency); - acpigen_write_dword(cstate->power); - acpigen_pop_len(); -} - -void acpigen_write_CST_package(acpi_cstate_t *cstate, int nentries) -{ - int i; - acpigen_write_name("_CST"); - acpigen_write_package(nentries+1); - acpigen_write_dword(nentries); - - for (i = 0; i < nentries; i++) - acpigen_write_CST_package_entry(cstate + i); - - acpigen_pop_len(); -} - -void acpigen_write_TSS_package(int entries, acpi_tstate_t *tstate_list) -{ -/* - Sample _TSS package with 100% and 50% duty cycles - Name (_TSS, Package (0x02) - { - Package(){100, 1000, 0, 0x00, 0) - Package(){50, 520, 0, 0x18, 0) - }) - */ - int i; - acpi_tstate_t *tstate = tstate_list; - - acpigen_write_name("_TSS"); - acpigen_write_package(entries); - - for (i = 0; i < entries; i++) { - acpigen_write_package(5); - acpigen_write_dword(tstate->percent); - acpigen_write_dword(tstate->power); - acpigen_write_dword(tstate->latency); - acpigen_write_dword(tstate->control); - acpigen_write_dword(tstate->status); - acpigen_pop_len(); - tstate++; - } - - acpigen_pop_len(); -} - -void acpigen_write_TSD_package(u32 domain, u32 numprocs, PSD_coord coordtype) -{ - acpigen_write_name("_TSD"); - acpigen_write_package(1); - acpigen_write_package(5); - acpigen_write_byte(5); // 5 values - acpigen_write_byte(0); // revision 0 - acpigen_write_dword(domain); - acpigen_write_dword(coordtype); - acpigen_write_dword(numprocs); - acpigen_pop_len(); - acpigen_pop_len(); -} - - - -void acpigen_write_mem32fixed(int readwrite, u32 base, u32 size) -{ - /* - * acpi 4.0 section 6.4.3.4: 32-Bit Fixed Memory Range Descriptor - * Byte 0: - * Bit7 : 1 => big item - * Bit6-0: 0000110 (0x6) => 32-bit fixed memory - */ - acpigen_emit_byte(0x86); - /* Byte 1+2: length (0x0009) */ - acpigen_emit_byte(0x09); - acpigen_emit_byte(0x00); - /* bit1-7 are ignored */ - acpigen_emit_byte(readwrite ? 0x01 : 0x00); - acpigen_emit_byte(base & 0xff); - acpigen_emit_byte((base >> 8) & 0xff); - acpigen_emit_byte((base >> 16) & 0xff); - acpigen_emit_byte((base >> 24) & 0xff); - acpigen_emit_byte(size & 0xff); - acpigen_emit_byte((size >> 8) & 0xff); - acpigen_emit_byte((size >> 16) & 0xff); - acpigen_emit_byte((size >> 24) & 0xff); -} - -void acpigen_write_register(acpi_addr_t *addr) -{ - acpigen_emit_byte(0x82); /* Register Descriptor */ - acpigen_emit_byte(0x0c); /* Register Length 7:0 */ - acpigen_emit_byte(0x00); /* Register Length 15:8 */ - acpigen_emit_byte(addr->space_id); /* Address Space ID */ - acpigen_emit_byte(addr->bit_width); /* Register Bit Width */ - acpigen_emit_byte(addr->bit_offset); /* Register Bit Offset */ - acpigen_emit_byte(addr->resv); /* Register Access Size */ - acpigen_emit_byte(addr->addrl & 0xff); /* Register Address Low */ - acpigen_emit_byte((addr->addrl >> 8) & 0xff); - acpigen_emit_byte((addr->addrl >> 16) & 0xff); - acpigen_emit_byte((addr->addrl >> 24) & 0xff); - acpigen_emit_byte(addr->addrh & 0xff); /* Register Address High */ - acpigen_emit_byte((addr->addrh >> 8) & 0xff); - acpigen_emit_byte((addr->addrh >> 16) & 0xff); - acpigen_emit_byte((addr->addrh >> 24) & 0xff); -} - -void acpigen_write_irq(u16 mask) -{ - /* - * acpi 3.0b section 6.4.2.1: IRQ Descriptor - * Byte 0: - * Bit7 : 0 => small item - * Bit6-3: 0100 (0x4) => IRQ port descriptor - * Bit2-0: 010 (0x2) => 2 Bytes long - */ - acpigen_emit_byte(0x22); - acpigen_emit_byte(mask & 0xff); - acpigen_emit_byte((mask >> 8) & 0xff); -} - -void acpigen_write_io16(u16 min, u16 max, u8 align, u8 len, u8 decode16) -{ - /* - * acpi 4.0 section 6.4.2.6: I/O Port Descriptor - * Byte 0: - * Bit7 : 0 => small item - * Bit6-3: 1000 (0x8) => I/O port descriptor - * Bit2-0: 111 (0x7) => 7 Bytes long - */ - acpigen_emit_byte(0x47); - /* Does the device decode all 16 or just 10 bits? */ - /* bit1-7 are ignored */ - acpigen_emit_byte(decode16 ? 0x01 : 0x00); - /* minimum base address the device may be configured for */ - acpigen_emit_byte(min & 0xff); - acpigen_emit_byte((min >> 8) & 0xff); - /* maximum base address the device may be configured for */ - acpigen_emit_byte(max & 0xff); - acpigen_emit_byte((max >> 8) & 0xff); - /* alignment for min base */ - acpigen_emit_byte(align & 0xff); - acpigen_emit_byte(len & 0xff); -} - -void acpigen_write_resourcetemplate_header(void) -{ - /* - * A ResourceTemplate() is a Buffer() with a - * (Byte|Word|DWord) containing the length, followed by one or more - * resource items, terminated by the end tag. - * (small item 0xf, len 1) - */ - acpigen_emit_byte(0x11); /* Buffer opcode */ - acpigen_write_len_f(); - acpigen_emit_byte(0x0b); /* Word opcode */ - len_stack[ltop++] = acpigen_get_current(); - acpigen_emit_byte(0x00); - acpigen_emit_byte(0x00); -} - -void acpigen_write_resourcetemplate_footer(void) -{ - char *p = len_stack[--ltop]; - int len; - /* - * end tag (acpi 4.0 Section 6.4.2.8) - * 0x79 <checksum> - * 0x00 is treated as a good checksum according to the spec - * and is what iasl generates. - */ - acpigen_emit_byte(0x79); - acpigen_emit_byte(0x00); - - len = gencurrent - p; - - /* patch len word */ - p[0] = len & 0xff; - p[1] = (len >> 8) & 0xff; - /* patch len field */ - acpigen_pop_len(); -} - -static void acpigen_add_mainboard_rsvd_mem32(void *gp, struct device *dev, - struct resource *res) -{ - acpigen_write_mem32fixed(0, res->base, res->size); -} - -static void acpigen_add_mainboard_rsvd_io(void *gp, struct device *dev, - struct resource *res) -{ - resource_t base = res->base; - resource_t size = res->size; - while (size > 0) { - resource_t sz = size > 255 ? 255 : size; - acpigen_write_io16(base, base, 0, sz, 1); - size -= sz; - base += sz; - } -} - -void acpigen_write_mainboard_resource_template(void) -{ - acpigen_write_resourcetemplate_header(); - - /* Add reserved memory ranges. */ - search_global_resources( - IORESOURCE_MEM | IORESOURCE_RESERVE, - IORESOURCE_MEM | IORESOURCE_RESERVE, - acpigen_add_mainboard_rsvd_mem32, 0); - - /* Add reserved io ranges. */ - search_global_resources( - IORESOURCE_IO | IORESOURCE_RESERVE, - IORESOURCE_IO | IORESOURCE_RESERVE, - acpigen_add_mainboard_rsvd_io, 0); - - acpigen_write_resourcetemplate_footer(); -} - -void acpigen_write_mainboard_resources(const char *scope, const char *name) -{ - acpigen_write_scope(scope); - acpigen_write_name(name); - acpigen_write_mainboard_resource_template(); - acpigen_pop_len(); -} - -static int hex2bin(const char c) -{ - if (c >= 'A' && c <= 'F') - return c - 'A' + 10; - if (c >= 'a' && c <= 'f') - return c - 'a' + 10; - return c - '0'; -} - -void acpigen_emit_eisaid(const char *eisaid) -{ - u32 compact = 0; - - /* Clamping individual values would be better but - there is a disagreement over what is a valid - EISA id, so accept anything and don't clamp, - parent code should create a valid EISAid. - */ - compact |= (eisaid[0] - 'A' + 1) << 26; - compact |= (eisaid[1] - 'A' + 1) << 21; - compact |= (eisaid[2] - 'A' + 1) << 16; - compact |= hex2bin(eisaid[3]) << 12; - compact |= hex2bin(eisaid[4]) << 8; - compact |= hex2bin(eisaid[5]) << 4; - compact |= hex2bin(eisaid[6]); - - acpigen_emit_byte(0xc); - acpigen_emit_byte((compact >> 24) & 0xff); - acpigen_emit_byte((compact >> 16) & 0xff); - acpigen_emit_byte((compact >> 8) & 0xff); - acpigen_emit_byte(compact & 0xff); -} diff --git a/src/arch/x86/boot/boot.c b/src/arch/x86/boot/boot.c deleted file mode 100644 index 7eb87fbef6..0000000000 --- a/src/arch/x86/boot/boot.c +++ /dev/null @@ -1,210 +0,0 @@ -#include <console/console.h> -#include <arch/stages.h> -#include <program_loading.h> -#include <ip_checksum.h> -#include <string.h> -#include <symbols.h> - -/* When the ramstage is relocatable the elf loading ensures an elf image cannot - * be loaded over the ramstage code. */ -static void jmp_payload_no_bounce_buffer(void *entry) -{ - /* Jump to kernel */ - __asm__ __volatile__( - " cld \n\t" - /* Now jump to the loaded image */ - " call *%0\n\t" - - /* The loaded image returned? */ - " cli \n\t" - " cld \n\t" - - :: - "r" (entry) - ); -} - -static void jmp_payload(void *entry, unsigned long buffer, unsigned long size) -{ - unsigned long lb_start, lb_size; - - lb_start = (unsigned long)&_program; - lb_size = _program_size; - - printk(BIOS_SPEW, "entry = 0x%08lx\n", (unsigned long)entry); - printk(BIOS_SPEW, "lb_start = 0x%08lx\n", lb_start); - printk(BIOS_SPEW, "lb_size = 0x%08lx\n", lb_size); - printk(BIOS_SPEW, "buffer = 0x%08lx\n", buffer); - - /* Jump to kernel */ - __asm__ __volatile__( - " cld \n\t" -#ifdef __x86_64__ - /* switch back to 32-bit mode */ - " push %4\n\t" - " push %3\n\t" - " push %2\n\t" - " push %1\n\t" - " push %0\n\t" - - ".intel_syntax noprefix\n\t" - /* use iret to switch to 32-bit code segment */ - " xor rax,rax\n\t" - " mov ax, ss\n\t" - " push rax\n\t" - " mov rax, rsp\n\t" - " add rax, 8\n\t" - " push rax\n\t" - " pushfq\n\t" - " push 0x10\n\t" - " lea rax,[rip+3]\n\t" - " push rax\n\t" - " iretq\n\t" - ".code32\n\t" - /* disable paging */ - " mov eax, cr0\n\t" - " btc eax, 31\n\t" - " mov cr0, eax\n\t" - /* disable long mode */ - " mov ecx, 0xC0000080\n\t" - " rdmsr\n\t" - " btc eax, 8\n\t" - " wrmsr\n\t" - - " pop eax\n\t" - " add esp, 4\n\t" - " pop ebx\n\t" - " add esp, 4\n\t" - " pop ecx\n\t" - - " add esp, 4\n\t" - " pop edx\n\t" - " add esp, 4\n\t" - " pop esi\n\t" - " add esp, 4\n\t" - - ".att_syntax prefix\n\t" -#endif - - /* Save the callee save registers... */ - " pushl %%esi\n\t" - " pushl %%edi\n\t" - " pushl %%ebx\n\t" - /* Save the parameters I was passed */ -#ifdef __x86_64__ - " pushl $0\n\t" /* 20 adjust */ - " pushl %%eax\n\t" /* 16 lb_start */ - " pushl %%ebx\n\t" /* 12 buffer */ - " pushl %%ecx\n\t" /* 8 lb_size */ - " pushl %%edx\n\t" /* 4 entry */ - " pushl %%esi\n\t" /* 0 elf_boot_notes */ -#else - " pushl $0\n\t" /* 20 adjust */ - " pushl %0\n\t" /* 16 lb_start */ - " pushl %1\n\t" /* 12 buffer */ - " pushl %2\n\t" /* 8 lb_size */ - " pushl %3\n\t" /* 4 entry */ - " pushl %4\n\t" /* 0 elf_boot_notes */ - -#endif - /* Compute the adjustment */ - " xorl %%eax, %%eax\n\t" - " subl 16(%%esp), %%eax\n\t" - " addl 12(%%esp), %%eax\n\t" - " addl 8(%%esp), %%eax\n\t" - " movl %%eax, 20(%%esp)\n\t" - /* Place a copy of coreboot in its new location */ - /* Move ``longs'' the coreboot size is 4 byte aligned */ - " movl 12(%%esp), %%edi\n\t" - " addl 8(%%esp), %%edi\n\t" - " movl 16(%%esp), %%esi\n\t" - " movl 8(%%esp), %%ecx\n\n" - " shrl $2, %%ecx\n\t" - " rep movsl\n\t" - - /* Adjust the stack pointer to point into the new coreboot image */ - " addl 20(%%esp), %%esp\n\t" - /* Adjust the instruction pointer to point into the new coreboot image */ - " movl $1f, %%eax\n\t" - " addl 20(%%esp), %%eax\n\t" - " jmp *%%eax\n\t" - "1: \n\t" - - /* Copy the coreboot bounce buffer over coreboot */ - /* Move ``longs'' the coreboot size is 4 byte aligned */ - " movl 16(%%esp), %%edi\n\t" - " movl 12(%%esp), %%esi\n\t" - " movl 8(%%esp), %%ecx\n\t" - " shrl $2, %%ecx\n\t" - " rep movsl\n\t" - - /* Now jump to the loaded image */ - " movl %5, %%eax\n\t" - " movl 0(%%esp), %%ebx\n\t" - " call *4(%%esp)\n\t" - - /* The loaded image returned? */ - " cli \n\t" - " cld \n\t" - - /* Copy the saved copy of coreboot where coreboot runs */ - /* Move ``longs'' the coreboot size is 4 byte aligned */ - " movl 16(%%esp), %%edi\n\t" - " movl 12(%%esp), %%esi\n\t" - " addl 8(%%esp), %%esi\n\t" - " movl 8(%%esp), %%ecx\n\t" - " shrl $2, %%ecx\n\t" - " rep movsl\n\t" - - /* Adjust the stack pointer to point into the old coreboot image */ - " subl 20(%%esp), %%esp\n\t" - - /* Adjust the instruction pointer to point into the old coreboot image */ - " movl $1f, %%eax\n\t" - " subl 20(%%esp), %%eax\n\t" - " jmp *%%eax\n\t" - "1: \n\t" - - /* Drop the parameters I was passed */ - " addl $24, %%esp\n\t" - - /* Restore the callee save registers */ - " popl %%ebx\n\t" - " popl %%edi\n\t" - " popl %%esi\n\t" -#ifdef __x86_64__ - ".code64\n\t" -#endif - :: - "ri" (lb_start), "ri" (buffer), "ri" (lb_size), - "ri" (entry), - "ri"(0), "ri" (0) - ); -} - -static void try_payload(struct prog *prog) -{ - if (prog_type(prog) == ASSET_PAYLOAD) { - if (IS_ENABLED(CONFIG_RELOCATABLE_RAMSTAGE)) - jmp_payload_no_bounce_buffer(prog_entry(prog)); - else - jmp_payload(prog_entry(prog), - (uintptr_t)prog_start(prog), - prog_size(prog)); - } -} - -void arch_prog_run(struct prog *prog) -{ - if (ENV_RAMSTAGE) - try_payload(prog); - __asm__ volatile ( -#ifdef __x86_64__ - "jmp *%%rdi\n" -#else - "jmp *%%edi\n" -#endif - - :: "D"(prog_entry(prog)) - ); -} diff --git a/src/arch/x86/boot/cbmem.c b/src/arch/x86/boot/cbmem.c deleted file mode 100644 index e279db960c..0000000000 --- a/src/arch/x86/boot/cbmem.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * 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. - */ - -#include <stdlib.h> -#include <console/console.h> -#include <cbmem.h> -#include <arch/acpi.h> - -#if IS_ENABLED(CONFIG_LATE_CBMEM_INIT) - -#if !defined(__PRE_RAM__) -void __attribute__((weak)) backup_top_of_ram(uint64_t ramtop) -{ - /* Do nothing. Chipset may have implementation to save ramtop in NVRAM. */ -} - -static void *ramtop_pointer; - -void set_top_of_ram(uint64_t ramtop) -{ - backup_top_of_ram(ramtop); - ramtop_pointer = (void *)(uintptr_t)ramtop; -} - -static inline void *saved_ramtop(void) -{ - return ramtop_pointer; -} -#else -static inline void *saved_ramtop(void) -{ - return NULL; -} -#endif /* !__PRE_RAM__ */ - -unsigned long __attribute__((weak)) get_top_of_ram(void) -{ - return 0; -} - -void *cbmem_top(void) -{ - /* Top of cbmem is at lowest usable DRAM address below 4GiB. */ - void *ptr = saved_ramtop(); - - if (ptr != NULL) - return ptr; - - return (void *)get_top_of_ram(); -} - -#endif /* LATE_CBMEM_INIT */ - -/* Something went wrong, our high memory area got wiped */ -void cbmem_fail_resume(void) -{ -#if !defined(__PRE_RAM__) && IS_ENABLED(CONFIG_HAVE_ACPI_RESUME) - /* ACPI resume needs to be cleared in the fail-to-recover case, but that - * condition is only handled during ramstage. */ - acpi_fail_wakeup(); -#endif -} diff --git a/src/arch/x86/boot/gdt.c b/src/arch/x86/boot/gdt.c deleted file mode 100644 index a21fab24ad..0000000000 --- a/src/arch/x86/boot/gdt.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2008-2009 coresystems GmbH - * - * 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. - */ - -#include <types.h> -#include <string.h> -#include <cbmem.h> -#include <console/console.h> -#include <cpu/x86/gdt.h> - -/* i386 lgdt argument */ -struct gdtarg { - u16 limit; -#ifdef __x86_64__ - u64 base; -#else - u32 base; -#endif -} __attribute__((packed)); - -/* Copy GDT to new location and reload it. - * FIXME: We only do this for BSP CPU. - */ -static void move_gdt(int is_recovery) -{ - void *newgdt; - u16 num_gdt_bytes = (uintptr_t)&gdt_end - (uintptr_t)&gdt; - struct gdtarg gdtarg; - - newgdt = cbmem_find(CBMEM_ID_GDT); - if (!newgdt) { - newgdt = cbmem_add(CBMEM_ID_GDT, ALIGN(num_gdt_bytes, 512)); - if (!newgdt) { - printk(BIOS_ERR, "Error: Could not relocate GDT.\n"); - return; - } - printk(BIOS_DEBUG, "Moving GDT to %p...", newgdt); - memcpy((void*)newgdt, &gdt, num_gdt_bytes); - } - - gdtarg.base = (uintptr_t)newgdt; - gdtarg.limit = num_gdt_bytes - 1; - - __asm__ __volatile__ ("lgdt %0\n\t" : : "m" (gdtarg)); - printk(BIOS_DEBUG, "ok\n"); -} -RAMSTAGE_CBMEM_INIT_HOOK(move_gdt) diff --git a/src/arch/x86/boot/mpspec.c b/src/arch/x86/boot/mpspec.c deleted file mode 100644 index 1a0ac31fd0..0000000000 --- a/src/arch/x86/boot/mpspec.c +++ /dev/null @@ -1,597 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2014 Sage Electronic Engineering, LLC. - * - * 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. - */ - -#include <console/console.h> -#include <device/path.h> -#include <device/pci_ids.h> -#include <cpu/cpu.h> -#include <arch/smp/mpspec.h> -#include <string.h> -#include <arch/cpu.h> -#include <cpu/x86/lapic.h> -#include <drivers/generic/ioapic/chip.h> - -/* Initialize the specified "mc" struct with initial values. */ -void mptable_init(struct mp_config_table *mc, u32 lapic_addr) -{ - int i; - - memset(mc, 0, sizeof(*mc)); - - memcpy(mc->mpc_signature, MPC_SIGNATURE, 4); - - mc->mpc_length = sizeof(*mc); /* Initially just the header size. */ - mc->mpc_spec = 0x04; /* MultiProcessor specification 1.4 */ - mc->mpc_checksum = 0; /* Not yet computed. */ - mc->mpc_oemptr = 0; - mc->mpc_oemsize = 0; - mc->mpc_entry_count = 0; /* No entries yet... */ - mc->mpc_lapic = lapic_addr; - mc->mpe_length = 0; - mc->mpe_checksum = 0; - mc->reserved = 0; - - strncpy(mc->mpc_oem, CONFIG_MAINBOARD_VENDOR, 8); - strncpy(mc->mpc_productid, CONFIG_MAINBOARD_PART_NUMBER, 12); - - /* - * The oem/productid fields are exactly 8/12 bytes long. If the resp. - * entry is shorter, the remaining bytes are filled with spaces. - */ - for (i = MIN(strlen(CONFIG_MAINBOARD_VENDOR), 8); i < 8; i++) - mc->mpc_oem[i] = ' '; - for (i = MIN(strlen(CONFIG_MAINBOARD_PART_NUMBER), 12); i < 12; i++) - mc->mpc_productid[i] = ' '; -} - -static unsigned char smp_compute_checksum(void *v, int len) -{ - unsigned char *bytes; - unsigned char checksum; - int i; - bytes = v; - checksum = 0; - for(i = 0; i < len; i++) { - checksum -= bytes[i]; - } - return checksum; -} - -static void *smp_write_floating_table_physaddr(uintptr_t addr, uintptr_t mpf_physptr, unsigned int virtualwire) -{ - struct intel_mp_floating *mf; - void *v; - - v = (void *)addr; - mf = v; - mf->mpf_signature[0] = '_'; - mf->mpf_signature[1] = 'M'; - mf->mpf_signature[2] = 'P'; - mf->mpf_signature[3] = '_'; - mf->mpf_physptr = mpf_physptr; - mf->mpf_length = 1; - mf->mpf_specification = 4; - mf->mpf_checksum = 0; - mf->mpf_feature1 = 0; - mf->mpf_feature2 = virtualwire?MP_FEATURE_PIC:MP_FEATURE_VIRTUALWIRE; - mf->mpf_feature3 = 0; - mf->mpf_feature4 = 0; - mf->mpf_feature5 = 0; - mf->mpf_checksum = smp_compute_checksum(mf, mf->mpf_length*16); - return v; -} - -void *smp_write_floating_table(unsigned long addr, unsigned int virtualwire) -{ - /* 16 byte align the table address */ - addr = (addr + 0xf) & (~0xf); - return smp_write_floating_table_physaddr(addr, addr + SMP_FLOATING_TABLE_LEN, virtualwire); -} - -void *smp_next_mpc_entry(struct mp_config_table *mc) -{ - void *v; - v = (void *)(((char *)mc) + mc->mpc_length); - - return v; -} -static void smp_add_mpc_entry(struct mp_config_table *mc, u16 length) -{ - mc->mpc_length += length; - mc->mpc_entry_count++; -} - -void *smp_next_mpe_entry(struct mp_config_table *mc) -{ - void *v; - v = (void *)(((char *)mc) + mc->mpc_length + mc->mpe_length); - - return v; -} -static void smp_add_mpe_entry(struct mp_config_table *mc, mpe_t mpe) -{ - mc->mpe_length += mpe->mpe_length; -} - -/* - * Type 0: Processor Entries: - * Entry Type, LAPIC ID, LAPIC Version, CPU Flags EN/BP, - * CPU Signature (Stepping, Model, Family), Feature Flags - */ -void smp_write_processor(struct mp_config_table *mc, - u8 apicid, u8 apicver, u8 cpuflag, - u32 cpufeature, u32 featureflag) -{ - struct mpc_config_processor *mpc; - mpc = smp_next_mpc_entry(mc); - memset(mpc, '\0', sizeof(*mpc)); - mpc->mpc_type = MP_PROCESSOR; - mpc->mpc_apicid = apicid; - mpc->mpc_apicver = apicver; - mpc->mpc_cpuflag = cpuflag; - mpc->mpc_cpufeature = cpufeature; - mpc->mpc_featureflag = featureflag; - smp_add_mpc_entry(mc, sizeof(*mpc)); -} - -/* - * If we assume a symmetric processor configuration we can - * get all of the information we need to write the processor - * entry from the bootstrap processor. - * Plus I don't think linux really even cares. - * Having the proper apicid's in the table so the non-bootstrap - * processors can be woken up should be enough. - */ -void smp_write_processors(struct mp_config_table *mc) -{ - int boot_apic_id; - int order_id; - unsigned apic_version; - unsigned cpu_features; - unsigned cpu_feature_flags; - struct cpuid_result result; - struct device *cpu; - - boot_apic_id = lapicid(); - apic_version = lapic_read(LAPIC_LVR) & 0xff; - result = cpuid(1); - cpu_features = result.eax; - cpu_feature_flags = result.edx; - /* order the output of the cpus to fix a bug in kernel 2.6.11 */ - for(order_id = 0;order_id <256; order_id++) { - for(cpu = all_devices; cpu; cpu = cpu->next) { - unsigned long cpu_flag; - if ((cpu->path.type != DEVICE_PATH_APIC) || - (cpu->bus->dev->path.type != DEVICE_PATH_CPU_CLUSTER)) - continue; - - if (!cpu->enabled) - continue; - - cpu_flag = MPC_CPU_ENABLED; - - if (boot_apic_id == cpu->path.apic.apic_id) - cpu_flag = MPC_CPU_ENABLED | MPC_CPU_BOOTPROCESSOR; - - if(cpu->path.apic.apic_id == order_id) { - smp_write_processor(mc, - cpu->path.apic.apic_id, apic_version, - cpu_flag, cpu_features, cpu_feature_flags - ); - break; - } - } - } -} - -/* - * Type 1: Bus Entries: - * Entry Type, Bus ID, Bus Type - */ -static void smp_write_bus(struct mp_config_table *mc, - u8 id, const char *bustype) -{ - struct mpc_config_bus *mpc; - mpc = smp_next_mpc_entry(mc); - memset(mpc, '\0', sizeof(*mpc)); - mpc->mpc_type = MP_BUS; - mpc->mpc_busid = id; - memcpy(mpc->mpc_bustype, bustype, sizeof(mpc->mpc_bustype)); - smp_add_mpc_entry(mc, sizeof(*mpc)); -} - -/* - * Type 2: I/O APIC Entries: - * Entry Type, APIC ID, Version, - * APIC Flags:EN, Address - */ -void smp_write_ioapic(struct mp_config_table *mc, - u8 id, u8 ver, void *apicaddr) -{ - struct mpc_config_ioapic *mpc; - mpc = smp_next_mpc_entry(mc); - memset(mpc, '\0', sizeof(*mpc)); - mpc->mpc_type = MP_IOAPIC; - mpc->mpc_apicid = id; - mpc->mpc_apicver = ver; - mpc->mpc_flags = MPC_APIC_USABLE; - mpc->mpc_apicaddr = apicaddr; - smp_add_mpc_entry(mc, sizeof(*mpc)); -} - -/* - * Type 3: I/O Interrupt Table Entries: - * Entry Type, Int Type, Int Polarity, Int Level, - * Source Bus ID, Source Bus IRQ, Dest APIC ID, Dest PIN# - */ -void smp_write_intsrc(struct mp_config_table *mc, - u8 irqtype, u16 irqflag, - u8 srcbus, u8 srcbusirq, - u8 dstapic, u8 dstirq) -{ - struct mpc_config_intsrc *mpc; - mpc = smp_next_mpc_entry(mc); - memset(mpc, '\0', sizeof(*mpc)); - mpc->mpc_type = MP_INTSRC; - mpc->mpc_irqtype = irqtype; - mpc->mpc_irqflag = irqflag; - mpc->mpc_srcbus = srcbus; - mpc->mpc_srcbusirq = srcbusirq; - mpc->mpc_dstapic = dstapic; - mpc->mpc_dstirq = dstirq; - smp_add_mpc_entry(mc, sizeof(*mpc)); -#ifdef DEBUG_MPTABLE - printk(BIOS_DEBUG, "add intsrc srcbus 0x%x srcbusirq 0x%x, dstapic 0x%x, dstirq 0x%x\n", - srcbus, srcbusirq, dstapic, dstirq); - hexdump(__func__, mpc, sizeof(*mpc)); -#endif -} - -/* - * Type 3: I/O Interrupt Table Entries for PCI Devices: - * This has the same fields as 'Type 3: I/O Interrupt Table Entries' - * but the Source Bus IRQ field has a slightly different - * definition: - * Bits 1-0: PIRQ pin: INT_A# = 0, INT_B# = 1, INT_C# = 2, INT_D# = 3 - * Bits 2-6: Originating PCI Device Number (Not its parent bridge device number) - * Bit 7: Reserved - */ -void smp_write_pci_intsrc(struct mp_config_table *mc, - u8 irqtype, u8 srcbus, u8 dev, u8 pirq, - u8 dstapic, u8 dstirq) -{ - u8 srcbusirq = (dev << 2) | pirq; - printk(BIOS_SPEW, "\tPCI srcbusirq = 0x%x from dev = 0x%x and pirq = %x\n", srcbusirq, dev, pirq); - smp_write_intsrc(mc, irqtype, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, srcbus, - srcbusirq, dstapic, dstirq); -} - -void smp_write_intsrc_pci_bridge(struct mp_config_table *mc, - u8 irqtype, u16 irqflag, struct device *dev, - unsigned char dstapic, unsigned char *dstirq) -{ - struct device *child; - - int i; - int srcbus; - int slot; - - struct bus *link; - unsigned char dstirq_x[4]; - - for (link = dev->link_list; link; link = link->next) { - - child = link->children; - srcbus = link->secondary; - - while (child) { - if (child->path.type != DEVICE_PATH_PCI) - goto next; - - slot = (child->path.pci.devfn >> 3); - /* round pins */ - for (i = 0; i < 4; i++) - dstirq_x[i] = dstirq[(i + slot) % 4]; - - if ((child->class >> 16) != PCI_BASE_CLASS_BRIDGE) { - /* pci device */ - printk(BIOS_DEBUG, "route irq: %s\n", dev_path(child)); - for (i = 0; i < 4; i++) - smp_write_intsrc(mc, irqtype, irqflag, srcbus, (slot<<2)|i, dstapic, dstirq_x[i]); - goto next; - } - - switch (child->class>>8) { - case PCI_CLASS_BRIDGE_PCI: - case PCI_CLASS_BRIDGE_PCMCIA: - case PCI_CLASS_BRIDGE_CARDBUS: - printk(BIOS_DEBUG, "route irq bridge: %s\n", dev_path(child)); - smp_write_intsrc_pci_bridge(mc, irqtype, irqflag, child, dstapic, dstirq_x); - } - -next: - child = child->sibling; - } - - } -} - -/* - * Type 4: Local Interrupt Assignment Entries: - * Entry Type, Int Type, Int Polarity, Int Level, - * Source Bus ID, Source Bus IRQ, Dest LAPIC ID, - * Dest LAPIC LINTIN# - */ -void smp_write_lintsrc(struct mp_config_table *mc, - u8 irqtype, u16 irqflag, - u8 srcbusid, u8 srcbusirq, - u8 destapic, u8 destapiclint) -{ - struct mpc_config_lintsrc *mpc; - mpc = smp_next_mpc_entry(mc); - memset(mpc, '\0', sizeof(*mpc)); - mpc->mpc_type = MP_LINTSRC; - mpc->mpc_irqtype = irqtype; - mpc->mpc_irqflag = irqflag; - mpc->mpc_srcbusid = srcbusid; - mpc->mpc_srcbusirq = srcbusirq; - mpc->mpc_destapic = destapic; - mpc->mpc_destapiclint = destapiclint; - smp_add_mpc_entry(mc, sizeof(*mpc)); -} - -/* - * Type 128: System Address Space Mapping Entries - * Entry Type, Entry Length, Bus ID, Address Type, - * Address Base Lo/Hi, Address Length Lo/Hi - */ -void smp_write_address_space(struct mp_config_table *mc, - u8 busid, u8 address_type, - u32 address_base_low, u32 address_base_high, - u32 address_length_low, u32 address_length_high) -{ - struct mp_exten_system_address_space *mpe; - mpe = smp_next_mpe_entry(mc); - memset(mpe, '\0', sizeof(*mpe)); - mpe->mpe_type = MPE_SYSTEM_ADDRESS_SPACE; - mpe->mpe_length = sizeof(*mpe); - mpe->mpe_busid = busid; - mpe->mpe_address_type = address_type; - mpe->mpe_address_base_low = address_base_low; - mpe->mpe_address_base_high = address_base_high; - mpe->mpe_address_length_low = address_length_low; - mpe->mpe_address_length_high = address_length_high; - smp_add_mpe_entry(mc, (mpe_t)mpe); -} - -/* - * Type 129: Bus Hierarchy Descriptor Entry - * Entry Type, Entry Length, Bus ID, Bus Info, - * Parent Bus ID - */ -void smp_write_bus_hierarchy(struct mp_config_table *mc, - u8 busid, u8 bus_info, u8 parent_busid) -{ - struct mp_exten_bus_hierarchy *mpe; - mpe = smp_next_mpe_entry(mc); - memset(mpe, '\0', sizeof(*mpe)); - mpe->mpe_type = MPE_BUS_HIERARCHY; - mpe->mpe_length = sizeof(*mpe); - mpe->mpe_busid = busid; - mpe->mpe_bus_info = bus_info; - mpe->mpe_parent_busid = parent_busid; - smp_add_mpe_entry(mc, (mpe_t)mpe); -} - -/* - * Type 130: Compatibility Bus Address Space Modifier Entry - * Entry Type, Entry Length, Bus ID, Address Modifier - * Predefined Range List - */ -void smp_write_compatibility_address_space(struct mp_config_table *mc, - u8 busid, u8 address_modifier, - u32 range_list) -{ - struct mp_exten_compatibility_address_space *mpe; - mpe = smp_next_mpe_entry(mc); - memset(mpe, '\0', sizeof(*mpe)); - mpe->mpe_type = MPE_COMPATIBILITY_ADDRESS_SPACE; - mpe->mpe_length = sizeof(*mpe); - mpe->mpe_busid = busid; - mpe->mpe_address_modifier = address_modifier; - mpe->mpe_range_list = range_list; - smp_add_mpe_entry(mc, (mpe_t)mpe); -} - -void mptable_lintsrc(struct mp_config_table *mc, unsigned long bus_isa) -{ - smp_write_lintsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, MP_APIC_ALL, 0x0); - smp_write_lintsrc(mc, mp_NMI, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, MP_APIC_ALL, 0x1); -} - -void mptable_add_isa_interrupts(struct mp_config_table *mc, unsigned long bus_isa, unsigned long apicid, int external_int2) -{ -/*I/O Ints: Type Trigger Polarity Bus ID IRQ APIC ID PIN# */ - smp_write_intsrc(mc, external_int2?mp_INT:mp_ExtINT, - MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, apicid, 0x0); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x1, apicid, 0x1); - smp_write_intsrc(mc, external_int2?mp_ExtINT:mp_INT, - MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, apicid, 0x2); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x3, apicid, 0x3); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x4, apicid, 0x4); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x6, apicid, 0x6); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x7, apicid, 0x7); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x8, apicid, 0x8); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x9, apicid, 0x9); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xa, apicid, 0xa); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xb, apicid, 0xb); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xc, apicid, 0xc); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xd, apicid, 0xd); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xe, apicid, 0xe); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xf, apicid, 0xf); -} - -void mptable_write_buses(struct mp_config_table *mc, int *max_pci_bus, int *isa_bus) { - int dummy, i, highest; - char buses[256]; - struct device *dev; - - if (!max_pci_bus) max_pci_bus = &dummy; - if (!isa_bus) isa_bus = &dummy; - - *max_pci_bus = 0; - highest = 0; - memset(buses, 0, sizeof(buses)); - - for (dev = all_devices; dev; dev = dev->next) { - struct bus *bus; - for (bus = dev->link_list; bus; bus = bus->next) { - if (bus->secondary > 255) { - printk(BIOS_ERR, "A bus claims to have a bus ID > 255?!? Aborting"); - return; - } - buses[bus->secondary] = 1; - if (highest < bus->secondary) highest = bus->secondary; - } - } - for (i=0; i <= highest; i++) { - if (buses[i]) { - smp_write_bus(mc, i, "PCI "); - *max_pci_bus = i; - } - } - *isa_bus = *max_pci_bus + 1; - smp_write_bus(mc, *isa_bus, "ISA "); -} - -void *mptable_finalize(struct mp_config_table *mc) -{ - mc->mpe_checksum = smp_compute_checksum(smp_next_mpc_entry(mc), mc->mpe_length); - mc->mpc_checksum = smp_compute_checksum(mc, mc->mpc_length); - printk(BIOS_DEBUG, "Wrote the mp table end at: %p - %p\n", mc, smp_next_mpe_entry(mc)); - return smp_next_mpe_entry(mc); -} - -unsigned long __attribute__((weak)) write_smp_table(unsigned long addr) -{ - struct drivers_generic_ioapic_config *ioapic_config; - struct mp_config_table *mc; - int isa_bus, pin, parentpin; - struct device *dev; - struct device *parent; - struct device *oldparent; - void *tmp, *v; - int isaioapic = -1, have_fixed_entries; - - v = smp_write_floating_table(addr, 0); - mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN); - - mptable_init(mc, LOCAL_APIC_ADDR); - - smp_write_processors(mc); - - mptable_write_buses(mc, NULL, &isa_bus); - - for(dev = all_devices; dev; dev = dev->next) { - if (dev->path.type != DEVICE_PATH_IOAPIC) - continue; - - if (!(ioapic_config = dev->chip_info)) { - printk(BIOS_ERR, "%s has no config, ignoring\n", dev_path(dev)); - continue; - } - smp_write_ioapic(mc, dev->path.ioapic.ioapic_id, - ioapic_config->version, - ioapic_config->base); - - if (ioapic_config->have_isa_interrupts) { - if (isaioapic >= 0) - printk(BIOS_ERR, "More than one IOAPIC with ISA interrupts?\n"); - else - isaioapic = dev->path.ioapic.ioapic_id; - } - } - - if (isaioapic >= 0) { - /* Legacy Interrupts */ - printk(BIOS_DEBUG, "Writing ISA IRQs\n"); - mptable_add_isa_interrupts(mc, isa_bus, isaioapic, 0); - } - - for(dev = all_devices; dev; dev = dev->next) { - - if (dev->path.type != DEVICE_PATH_PCI || !dev->enabled) - continue; - - have_fixed_entries = 0; - for (pin = 0; pin < 4; pin++) { - if (dev->pci_irq_info[pin].ioapic_dst_id) { - printk(BIOS_DEBUG, "fixed IRQ entry for: %s: INT%c# -> IOAPIC %d PIN %d\n", dev_path(dev), - pin + 'A', - dev->pci_irq_info[pin].ioapic_dst_id, - dev->pci_irq_info[pin].ioapic_irq_pin); - smp_write_intsrc(mc, mp_INT, - dev->pci_irq_info[pin].ioapic_flags, - dev->bus->secondary, - ((dev->path.pci.devfn & 0xf8) >> 1) | pin, - dev->pci_irq_info[pin].ioapic_dst_id, - dev->pci_irq_info[pin].ioapic_irq_pin); - have_fixed_entries = 1; - } - } - - if (!have_fixed_entries) { - pin = (dev->path.pci.devfn & 7) % 4; - oldparent = parent = dev; - while((parent = parent->bus->dev)) { - parentpin = (oldparent->path.pci.devfn >> 3) + (oldparent->path.pci.devfn & 7); - parentpin += dev->path.pci.devfn & 7; - parentpin += dev->path.pci.devfn >> 3; - parentpin %= 4; - - if (parent->pci_irq_info[parentpin].ioapic_dst_id) { - printk(BIOS_DEBUG, "automatic IRQ entry for %s: INT%c# -> IOAPIC %d PIN %d\n", - dev_path(dev), pin + 'A', - parent->pci_irq_info[parentpin].ioapic_dst_id, - parent->pci_irq_info[parentpin].ioapic_irq_pin); - smp_write_intsrc(mc, mp_INT, - parent->pci_irq_info[parentpin].ioapic_flags, - dev->bus->secondary, - ((dev->path.pci.devfn & 0xf8) >> 1) | pin, - parent->pci_irq_info[parentpin].ioapic_dst_id, - parent->pci_irq_info[parentpin].ioapic_irq_pin); - - break; - } - - if (parent->path.type == DEVICE_PATH_DOMAIN) { - printk(BIOS_WARNING, "no IRQ found for %s\n", dev_path(dev)); - break; - } - oldparent = parent; - } - } - } - - mptable_lintsrc(mc, isa_bus); - tmp = mptable_finalize(mc); - printk(BIOS_INFO, "MPTABLE len: %d\n", (unsigned int)((uintptr_t)tmp - - (uintptr_t)v)); - return (unsigned long)tmp; -} diff --git a/src/arch/x86/boot/pirq_routing.c b/src/arch/x86/boot/pirq_routing.c deleted file mode 100644 index 7fe20b25ab..0000000000 --- a/src/arch/x86/boot/pirq_routing.c +++ /dev/null @@ -1,208 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2012 Alexandru Gagniuc <mr.nuke.me@gmail.com> - * Copyright (C) 2010 Stefan Reinauer <stepan@coreboot.org> - * - * 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, either version 2 of the License, or - * (at your option) any later version. - * - * 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, see <http://www.gnu.org/licenses/>. - */ -#include <console/console.h> -#include <arch/pirq_routing.h> -#include <string.h> -#include <device/pci.h> - -#if CONFIG_DEBUG_PIRQ -static void check_pirq_routing_table(struct irq_routing_table *rt) -{ - uint8_t *addr = (uint8_t *)rt; - uint8_t sum=0; - int i; - - printk(BIOS_INFO, "Checking Interrupt Routing Table consistency...\n"); - - if (sizeof(struct irq_routing_table) != rt->size) { - printk(BIOS_WARNING, "Inconsistent Interrupt Routing Table size (0x%x/0x%x).\n", - (unsigned int) sizeof(struct irq_routing_table), - rt->size - ); - rt->size=sizeof(struct irq_routing_table); - } - - for (i = 0; i < rt->size; i++) - sum += addr[i]; - - printk(BIOS_DEBUG, "%s(): Interrupt Routing Table located at %p.\n", - __func__, addr); - - - sum = rt->checksum - sum; - - if (sum != rt->checksum) { - printk(BIOS_WARNING, "Interrupt Routing Table checksum is: 0x%02x but should be: 0x%02x.\n", - rt->checksum, sum); - rt->checksum = sum; - } - - if (rt->signature != PIRQ_SIGNATURE || rt->version != PIRQ_VERSION || - rt->size % 16 ) { - printk(BIOS_WARNING, "Interrupt Routing Table not valid.\n"); - return; - } - - sum = 0; - for (i=0; i<rt->size; i++) - sum += addr[i]; - - /* We're manually fixing the checksum above. This warning can probably - * never happen because if the target location is read-only this - * function would have bailed out earlier. - */ - if (sum) { - printk(BIOS_WARNING, "Checksum error in Interrupt Routing Table " - "could not be fixed.\n"); - } - - printk(BIOS_INFO, "done.\n"); -} - -static int verify_copy_pirq_routing_table(unsigned long addr, const struct irq_routing_table *routing_table) -{ - int i; - uint8_t *rt_orig, *rt_curr; - - rt_curr = (uint8_t*)addr; - rt_orig = (uint8_t*)routing_table; - printk(BIOS_INFO, "Verifying copy of Interrupt Routing Table at 0x%08lx... ", addr); - for (i = 0; i < routing_table->size; i++) { - if (*(rt_curr + i) != *(rt_orig + i)) { - printk(BIOS_INFO, "failed\n"); - return -1; - } - } - printk(BIOS_INFO, "done\n"); - - check_pirq_routing_table((struct irq_routing_table *)addr); - - return 0; -} -#endif - -#if CONFIG_PIRQ_ROUTE -static u8 pirq_get_next_free_irq(u8* pirq, u16 bitmap) -{ - int i, link; - u8 irq = 0; - for (i = 2; i <= 15; i++) - { - /* Can we assign this IRQ ? */ - if (!((bitmap >> i) & 1)) - continue; - /* We can, Now let's assume we can use this IRQ */ - irq = i; - /* And assume we have not yet routed it */ - int already_routed = 0; - /* Have we already routed it ? */ - for(link = 0; link < CONFIG_MAX_PIRQ_LINKS; link++) { - if (pirq[link] == irq) { - already_routed = 1; - break; - } - } - /* If it's not yet routed, use it */ - if(!already_routed) - break; - /* But if it was already routed, try the next one */ - continue; - } - /* Now we got our IRQ */ - return irq; -} - -static void pirq_route_irqs(unsigned long addr) -{ - int i, intx, num_entries; - unsigned char irq_slot[MAX_INTX_ENTRIES]; - unsigned char pirq[CONFIG_MAX_PIRQ_LINKS]; - struct irq_routing_table *pirq_tbl; - - memset(pirq, 0, CONFIG_MAX_PIRQ_LINKS); - - pirq_tbl = (struct irq_routing_table *)(addr); - num_entries = (pirq_tbl->size - 32) / 16; - - /* Set PCI IRQs. */ - for (i = 0; i < num_entries; i++) { - - printk(BIOS_DEBUG, "PIRQ Entry %d Dev/Fn: %X Slot: %d\n", i, - pirq_tbl->slots[i].devfn >> 3, pirq_tbl->slots[i].slot); - - for (intx = 0; intx < MAX_INTX_ENTRIES; intx++) { - - int link = pirq_tbl->slots[i].irq[intx].link; - int bitmap = pirq_tbl->slots[i].irq[intx].bitmap; - int irq = 0; - - printk(BIOS_DEBUG, "INT: %c link: %x bitmap: %x ", - 'A' + intx, link, bitmap); - - if (!bitmap|| !link || link > CONFIG_MAX_PIRQ_LINKS) { - - printk(BIOS_DEBUG, "not routed\n"); - irq_slot[intx] = irq; - continue; - } - - /* yet not routed */ - if (!pirq[link - 1]) - { - irq = pirq_get_next_free_irq(pirq, bitmap); - if (irq) - pirq[link - 1] = irq; - } - else - irq = pirq[link - 1]; - - printk(BIOS_DEBUG, "IRQ: %d\n", irq); - irq_slot[intx] = irq; - } - - /* Bus, device, slots IRQs for {A,B,C,D}. */ - pci_assign_irqs(pirq_tbl->slots[i].bus, - pirq_tbl->slots[i].devfn >> 3, irq_slot); - } - - for(i = 0; i < CONFIG_MAX_PIRQ_LINKS; i++) - printk(BIOS_DEBUG, "PIRQ%c: %d\n", i + 'A', pirq[i]); - - pirq_assign_irqs(pirq); -} -#endif - -unsigned long copy_pirq_routing_table(unsigned long addr, const struct irq_routing_table *routing_table) -{ - /* Align the table to be 16 byte aligned. */ - addr = ALIGN(addr, 16); - - /* This table must be between 0xf0000 & 0x100000 */ - printk(BIOS_INFO, "Copying Interrupt Routing Table to 0x%08lx... ", addr); - memcpy((void *)addr, routing_table, routing_table->size); - printk(BIOS_INFO, "done.\n"); -#if CONFIG_DEBUG_PIRQ - verify_copy_pirq_routing_table(addr, routing_table); -#endif -#if CONFIG_PIRQ_ROUTE - pirq_route_irqs(addr); -#endif - return addr + routing_table->size; -} diff --git a/src/arch/x86/boot/smbios.c b/src/arch/x86/boot/smbios.c deleted file mode 100644 index a1f05daeaf..0000000000 --- a/src/arch/x86/boot/smbios.c +++ /dev/null @@ -1,581 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering - * Copyright (C) 2011 Sven Schnelle <svens@stackframe.org> - * - * 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. - */ - -#include <stdlib.h> -#include <string.h> -#include <smbios.h> -#include <console/console.h> -#include <version.h> -#include <device/device.h> -#include <arch/cpu.h> -#include <cpu/x86/name.h> -#include <elog.h> -#include <endian.h> -#include <memory_info.h> -#include <spd.h> -#include <cbmem.h> -#if CONFIG_CHROMEOS -#include <vendorcode/google/chromeos/gnvs.h> -#endif - -static u8 smbios_checksum(u8 *p, u32 length) -{ - u8 ret = 0; - while (length--) - ret += *p++; - return -ret; -} - - -int smbios_add_string(char *start, const char *str) -{ - int i = 1; - char *p = start; - - for(;;) { - if (!*p) { - strcpy(p, str); - p += strlen(str); - *p++ = '\0'; - *p++ = '\0'; - return i; - } - - if (!strcmp(p, str)) - return i; - - p += strlen(p)+1; - i++; - } -} - -int smbios_string_table_len(char *start) -{ - char *p = start; - int i, len = 0; - - while(*p) { - i = strlen(p) + 1; - p += i; - len += i; - } - return len + 1; -} - -static int smbios_cpu_vendor(char *start) -{ - char tmp[13] = "Unknown"; - u32 *_tmp = (u32 *)tmp; - struct cpuid_result res; - - if (cpu_have_cpuid()) { - res = cpuid(0); - _tmp[0] = res.ebx; - _tmp[1] = res.edx; - _tmp[2] = res.ecx; - tmp[12] = '\0'; - } - - return smbios_add_string(start, tmp); -} - -static int smbios_processor_name(char *start) -{ - char tmp[49] = "Unknown Processor Name"; - u32 *_tmp = (u32 *)tmp; - struct cpuid_result res; - int i; - - if (cpu_have_cpuid()) { - res = cpuid(0x80000000); - if (res.eax >= 0x80000004) { - for (i = 0; i < 3; i++) { - res = cpuid(0x80000002 + i); - _tmp[i * 4 + 0] = res.eax; - _tmp[i * 4 + 1] = res.ebx; - _tmp[i * 4 + 2] = res.ecx; - _tmp[i * 4 + 3] = res.edx; - } - tmp[48] = 0; - } - } - return smbios_add_string(start, tmp); -} - -/* this function will fill the corresponding manufacturer */ -void smbios_fill_dimm_manufacturer_from_id(uint16_t mod_id, struct smbios_type17 *t) -{ - switch (mod_id) { - case 0x987f: - t->manufacturer = smbios_add_string(t->eos, - "Hynix"); - break; - case 0xad80: - t->manufacturer = smbios_add_string(t->eos, - "Hynix/Hyundai"); - break; - case 0xce80: - t->manufacturer = smbios_add_string(t->eos, - "Samsung"); - break; - case 0xfe02: - t->manufacturer = smbios_add_string(t->eos, - "Elpida"); - break; - case 0xff2c: - t->manufacturer = smbios_add_string(t->eos, - "Micron"); - break; - default: { - char string_buffer[256]; - snprintf(string_buffer, sizeof(string_buffer), - "Unknown (%x)", mod_id); - t->manufacturer = smbios_add_string(t->eos, - string_buffer); - break; - } - } -} - -static int create_smbios_type17_for_dimm(struct dimm_info *dimm, - unsigned long *current, int *handle) -{ - struct smbios_type17 *t = (struct smbios_type17 *)*current; - uint8_t length; - char locator[40]; - - memset(t, 0, sizeof(struct smbios_type17)); - t->memory_type = dimm->ddr_type; - t->clock_speed = dimm->ddr_frequency; - t->speed = dimm->ddr_frequency; - t->type = SMBIOS_MEMORY_DEVICE; - t->size = dimm->dimm_size; - t->data_width = 8 * (1 << (dimm->bus_width & 0x7)); - t->total_width = t->data_width + 8 * ((dimm->bus_width & 0x18) >> 3); - - switch (dimm->mod_type) { - case SPD_RDIMM: - case SPD_MINI_RDIMM: - t->form_factor = MEMORY_FORMFACTOR_RIMM; - break; - case SPD_UDIMM: - case SPD_MICRO_DIMM: - case SPD_MINI_UDIMM: - t->form_factor = MEMORY_FORMFACTOR_DIMM; - break; - case SPD_SODIMM: - t->form_factor = MEMORY_FORMFACTOR_SODIMM; - break; - default: - t->form_factor = MEMORY_FORMFACTOR_UNKNOWN; - break; - } - - smbios_fill_dimm_manufacturer_from_id(dimm->mod_id, t); - /* put '\0' in the end of data */ - length = sizeof(dimm->serial); - dimm->serial[length - 1] = '\0'; - if (dimm->serial[0] == 0) - t->serial_number = smbios_add_string(t->eos, "None"); - else - t->serial_number = smbios_add_string(t->eos, - (const char *)dimm->serial); - - snprintf(locator, sizeof(locator), "Channel-%d-DIMM-%d", - dimm->channel_num, dimm->dimm_num); - t->device_locator = smbios_add_string(t->eos, locator); - - snprintf(locator, sizeof(locator), "BANK %d", dimm->bank_locator); - t->bank_locator = smbios_add_string(t->eos, locator); - - /* put '\0' in the end of data */ - length = sizeof(dimm->module_part_number); - dimm->module_part_number[length - 1] = '\0'; - t->part_number = smbios_add_string(t->eos, - (const char *)dimm->module_part_number); - - /* Synchronous = 1 */ - t->type_detail = 0x0080; - /* no handle for error information */ - t->memory_error_information_handle = 0xFFFE; - t->attributes = dimm->rank_per_dimm; - t->handle = *handle; - *handle += 1; - t->length = sizeof(struct smbios_type17) - 2; - return t->length + smbios_string_table_len(t->eos); -} - -const char *__attribute__((weak)) smbios_mainboard_bios_version(void) -{ - if (strlen(CONFIG_LOCALVERSION)) - return CONFIG_LOCALVERSION; - else - return coreboot_version; -} - -static int smbios_write_type0(unsigned long *current, int handle) -{ - struct smbios_type0 *t = (struct smbios_type0 *)*current; - int len = sizeof(struct smbios_type0); - - memset(t, 0, sizeof(struct smbios_type0)); - t->type = SMBIOS_BIOS_INFORMATION; - t->handle = handle; - t->length = len - 2; - - t->vendor = smbios_add_string(t->eos, "coreboot"); -#if !CONFIG_CHROMEOS - t->bios_release_date = smbios_add_string(t->eos, coreboot_dmi_date); - - t->bios_version = smbios_add_string(t->eos, smbios_mainboard_bios_version()); -#else -#define SPACES \ - " " - t->bios_release_date = smbios_add_string(t->eos, coreboot_dmi_date); -#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES) - u32 version_offset = (u32)smbios_string_table_len(t->eos); -#endif - t->bios_version = smbios_add_string(t->eos, SPACES); - -#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES) - /* SMBIOS offsets start at 1 rather than 0 */ - vboot_data->vbt10 = (u32)t->eos + (version_offset - 1); -#endif -#endif /* CONFIG_CHROMEOS */ - - t->bios_rom_size = (CONFIG_ROM_SIZE / 65535) - 1; - - t->system_bios_major_release = 4; - t->bios_characteristics = - BIOS_CHARACTERISTICS_PCI_SUPPORTED | -#if CONFIG_CARDBUS_PLUGIN_SUPPORT - BIOS_CHARACTERISTICS_PC_CARD | -#endif - BIOS_CHARACTERISTICS_SELECTABLE_BOOT | - BIOS_CHARACTERISTICS_UPGRADEABLE; - -#if CONFIG_HAVE_ACPI_TABLES - t->bios_characteristics_ext1 = BIOS_EXT1_CHARACTERISTICS_ACPI; -#endif - t->bios_characteristics_ext2 = BIOS_EXT2_CHARACTERISTICS_TARGET; - len = t->length + smbios_string_table_len(t->eos); - *current += len; - return len; -} - -#if !CONFIG_SMBIOS_PROVIDED_BY_MOBO - -const char *__attribute__((weak)) smbios_mainboard_serial_number(void) -{ - return CONFIG_MAINBOARD_SERIAL_NUMBER; -} - -const char *__attribute__((weak)) smbios_mainboard_version(void) -{ - return CONFIG_MAINBOARD_VERSION; -} - -const char *__attribute__((weak)) smbios_mainboard_manufacturer(void) -{ - return CONFIG_MAINBOARD_SMBIOS_MANUFACTURER; -} - -const char *__attribute__((weak)) smbios_mainboard_product_name(void) -{ - return CONFIG_MAINBOARD_SMBIOS_PRODUCT_NAME; -} - -void __attribute__((weak)) smbios_mainboard_set_uuid(u8 *uuid) -{ - /* leave all zero */ -} -#endif - -#ifdef CONFIG_MAINBOARD_FAMILY -const char *smbios_mainboard_family(void) -{ - return CONFIG_MAINBOARD_FAMILY; -} -#endif /* CONFIG_MAINBOARD_FAMILY */ - -static int smbios_write_type1(unsigned long *current, int handle) -{ - struct smbios_type1 *t = (struct smbios_type1 *)*current; - int len = sizeof(struct smbios_type1); - - memset(t, 0, sizeof(struct smbios_type1)); - t->type = SMBIOS_SYSTEM_INFORMATION; - t->handle = handle; - t->length = len - 2; - t->manufacturer = smbios_add_string(t->eos, smbios_mainboard_manufacturer()); - t->product_name = smbios_add_string(t->eos, smbios_mainboard_product_name()); - t->serial_number = smbios_add_string(t->eos, smbios_mainboard_serial_number()); - t->version = smbios_add_string(t->eos, smbios_mainboard_version()); -#ifdef CONFIG_MAINBOARD_FAMILY - t->family = smbios_add_string(t->eos, smbios_mainboard_family()); -#endif - smbios_mainboard_set_uuid(t->uuid); - len = t->length + smbios_string_table_len(t->eos); - *current += len; - return len; -} - -static int smbios_write_type2(unsigned long *current, int handle) -{ - struct smbios_type2 *t = (struct smbios_type2 *)*current; - int len = sizeof(struct smbios_type2); - - memset(t, 0, sizeof(struct smbios_type2)); - t->type = SMBIOS_BOARD_INFORMATION; - t->handle = handle; - t->length = len - 2; - t->manufacturer = smbios_add_string(t->eos, smbios_mainboard_manufacturer()); - t->product_name = smbios_add_string(t->eos, smbios_mainboard_product_name()); - t->serial_number = smbios_add_string(t->eos, smbios_mainboard_serial_number()); - t->version = smbios_add_string(t->eos, smbios_mainboard_version()); - len = t->length + smbios_string_table_len(t->eos); - *current += len; - return len; -} - -static int smbios_write_type3(unsigned long *current, int handle) -{ - struct smbios_type3 *t = (struct smbios_type3 *)*current; - int len = sizeof(struct smbios_type3); - - memset(t, 0, sizeof(struct smbios_type3)); - t->type = SMBIOS_SYSTEM_ENCLOSURE; - t->handle = handle; - t->length = len - 2; - t->manufacturer = smbios_add_string(t->eos, smbios_mainboard_manufacturer()); - t->bootup_state = SMBIOS_STATE_SAFE; - t->power_supply_state = SMBIOS_STATE_SAFE; - t->thermal_state = SMBIOS_STATE_SAFE; - if(IS_ENABLED(CONFIG_SYSTEM_TYPE_LAPTOP)) { - t->_type = SMBIOS_ENCLOSURE_NOTEBOOK; - } else { - t->_type = SMBIOS_ENCLOSURE_DESKTOP; - } - t->security_status = SMBIOS_STATE_SAFE; - len = t->length + smbios_string_table_len(t->eos); - *current += len; - return len; -} - -static int smbios_write_type4(unsigned long *current, int handle) -{ - struct cpuid_result res; - struct smbios_type4 *t = (struct smbios_type4 *)*current; - int len = sizeof(struct smbios_type4); - - /* Provide sane defaults even for CPU without CPUID */ - res.eax = res.edx = 0; - res.ebx = 0x10000; - - if (cpu_have_cpuid()) { - res = cpuid(1); - } - - memset(t, 0, sizeof(struct smbios_type4)); - t->type = SMBIOS_PROCESSOR_INFORMATION; - t->handle = handle; - t->length = len - 2; - t->processor_id[0] = res.eax; - t->processor_id[1] = res.edx; - t->processor_manufacturer = smbios_cpu_vendor(t->eos); - t->processor_version = smbios_processor_name(t->eos); - t->processor_family = (res.eax > 0) ? 0x0c : 0x6; - t->processor_type = 3; /* System Processor */ - t->processor_upgrade = 0x06; - t->core_count = (res.ebx >> 16) & 0xff; - t->l1_cache_handle = 0xffff; - t->l2_cache_handle = 0xffff; - t->l3_cache_handle = 0xffff; - t->processor_upgrade = 1; - len = t->length + smbios_string_table_len(t->eos); - *current += len; - return len; -} - -static int smbios_write_type11(unsigned long *current, int *handle) -{ - struct smbios_type11 *t = (struct smbios_type11 *)*current; - int len; - struct device *dev; - - memset(t, 0, sizeof *t); - t->type = SMBIOS_OEM_STRINGS; - t->handle = *handle; - t->length = len = sizeof *t - 2; - - for(dev = all_devices; dev; dev = dev->next) { - if (dev->ops && dev->ops->get_smbios_strings) - dev->ops->get_smbios_strings(dev, t); - } - - if (t->count == 0) { - memset(t, 0, sizeof *t); - return 0; - } - - len += smbios_string_table_len(t->eos); - - *current += len; - (*handle)++; - return len; -} - -static int smbios_write_type17(unsigned long *current, int *handle) -{ - int len = sizeof(struct smbios_type17); - int i; - - struct memory_info *meminfo; - meminfo = cbmem_find(CBMEM_ID_MEMINFO); - if (meminfo == NULL) - return 0; /* can't find mem info in cbmem */ - - printk(BIOS_INFO, "Create SMBIOS type 17\n"); - for (i = 0; i < meminfo->dimm_cnt && i < ARRAY_SIZE(meminfo->dimm); i++) { - struct dimm_info *dimm; - dimm = &meminfo->dimm[i]; - len = create_smbios_type17_for_dimm(dimm, current, handle); - *current += len; - } - return meminfo->dimm_cnt * len; -} - -static int smbios_write_type32(unsigned long *current, int handle) -{ - struct smbios_type32 *t = (struct smbios_type32 *)*current; - int len = sizeof(struct smbios_type32); - - memset(t, 0, sizeof(struct smbios_type32)); - t->type = SMBIOS_SYSTEM_BOOT_INFORMATION; - t->handle = handle; - t->length = len - 2; - *current += len; - return len; -} - -int smbios_write_type41(unsigned long *current, int *handle, - const char *name, u8 instance, u16 segment, - u8 bus, u8 device, u8 function) -{ - struct smbios_type41 *t = (struct smbios_type41 *)*current; - int len = sizeof(struct smbios_type41); - - memset(t, 0, sizeof(struct smbios_type41)); - t->type = SMBIOS_ONBOARD_DEVICES_EXTENDED_INFORMATION; - t->handle = *handle; - t->length = len - 2; - t->reference_designation = smbios_add_string(t->eos, name); - t->device_type = SMBIOS_DEVICE_TYPE_OTHER; - t->device_status = 1; - t->device_type_instance = instance; - t->segment_group_number = segment; - t->bus_number = bus; - t->device_number = device; - t->function_number = function; - - len = t->length + smbios_string_table_len(t->eos); - *current += len; - *handle += 1; - return len; -} - -static int smbios_write_type127(unsigned long *current, int handle) -{ - struct smbios_type127 *t = (struct smbios_type127 *)*current; - int len = sizeof(struct smbios_type127); - - memset(t, 0, sizeof(struct smbios_type127)); - t->type = SMBIOS_END_OF_TABLE; - t->handle = handle; - t->length = len - 2; - *current += len; - return len; -} - -static int smbios_walk_device_tree(struct device *tree, int *handle, unsigned long *current) -{ - struct device *dev; - int len = 0; - - for(dev = tree; dev; dev = dev->next) { - printk(BIOS_INFO, "%s (%s)\n", dev_path(dev), dev_name(dev)); - - if (dev->ops && dev->ops->get_smbios_data) - len += dev->ops->get_smbios_data(dev, handle, current); - } - return len; -} - -#define update_max(len, max_len, stmt) do { int tmp = stmt; max_len = MAX(max_len, tmp); len += tmp; } while(0) -unsigned long smbios_write_tables(unsigned long current) -{ - struct smbios_entry *se; - unsigned long tables; - int len = 0; - int max_struct_size = 0; - int handle = 0; - - current = ALIGN(current, 16); - printk(BIOS_DEBUG, "%s: %08lx\n", __func__, current); - - se = (struct smbios_entry *)current; - current += sizeof(struct smbios_entry); - current = ALIGN(current, 16); - - tables = current; - update_max(len, max_struct_size, smbios_write_type0(¤t, handle++)); - update_max(len, max_struct_size, smbios_write_type1(¤t, handle++)); - update_max(len, max_struct_size, smbios_write_type2(¤t, handle++)); - update_max(len, max_struct_size, smbios_write_type3(¤t, handle++)); - update_max(len, max_struct_size, smbios_write_type4(¤t, handle++)); - update_max(len, max_struct_size, smbios_write_type11(¤t, &handle)); -#if CONFIG_ELOG - update_max(len, max_struct_size, elog_smbios_write_type15(¤t, handle++)); -#endif - update_max(len, max_struct_size, smbios_write_type17(¤t, &handle)); - update_max(len, max_struct_size, smbios_write_type32(¤t, handle++)); - - update_max(len, max_struct_size, smbios_walk_device_tree(all_devices, &handle, ¤t)); - - update_max(len, max_struct_size, smbios_write_type127(¤t, handle++)); - - memset(se, 0, sizeof(struct smbios_entry)); - memcpy(se->anchor, "_SM_", 4); - se->length = sizeof(struct smbios_entry); - se->major_version = 2; - se->minor_version = 7; - se->max_struct_size = max_struct_size; - se->struct_count = handle; - memcpy(se->intermediate_anchor_string, "_DMI_", 5); - - se->struct_table_address = (u32)tables; - se->struct_table_length = len; - - se->intermediate_checksum = smbios_checksum((u8 *)se + 0x10, - sizeof(struct smbios_entry) - 0x10); - se->checksum = smbios_checksum((u8 *)se, sizeof(struct smbios_entry)); - return current; -} diff --git a/src/arch/x86/boot/tables.c b/src/arch/x86/boot/tables.c deleted file mode 100644 index 3d645633f0..0000000000 --- a/src/arch/x86/boot/tables.c +++ /dev/null @@ -1,221 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2003 Eric Biederman - * Copyright (C) 2005 Steve Magnani - * Copyright (C) 2008-2009 coresystems GmbH - * - * 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. - */ - -#include <console/console.h> -#include <cpu/cpu.h> -#include <boot/tables.h> -#include <boot/coreboot_tables.h> -#include <arch/pirq_routing.h> -#include <arch/smp/mpspec.h> -#include <arch/acpi.h> -#include <string.h> -#include <cbmem.h> -#include <smbios.h> - -void write_tables(void) -{ - unsigned long low_table_start, low_table_end; - unsigned long rom_table_start, rom_table_end; - - /* Even if high tables are configured, some tables are copied both to - * the low and the high area, so payloads and OSes don't need to know - * about the high tables. - */ - unsigned long high_table_pointer; - - rom_table_start = 0xf0000; - rom_table_end = 0xf0000; - - /* Start low addr at 0x500, so we don't run into conflicts with the BDA - * in case our data structures grow beyond 0x400. Only GDT - * and the coreboot table use low_tables. - */ - low_table_start = 0; - low_table_end = 0x500; - -#if CONFIG_GENERATE_PIRQ_TABLE -#define MAX_PIRQ_TABLE_SIZE (4 * 1024) - post_code(0x9a); - - /* This table must be between 0x0f0000 and 0x100000 */ - rom_table_end = write_pirq_routing_table(rom_table_end); - rom_table_end = ALIGN(rom_table_end, 1024); - - /* And add a high table version for those payloads that - * want to live in the F segment - */ - high_table_pointer = (unsigned long)cbmem_add(CBMEM_ID_PIRQ, MAX_PIRQ_TABLE_SIZE); - if (high_table_pointer) { - unsigned long new_high_table_pointer; - new_high_table_pointer = write_pirq_routing_table(high_table_pointer); - // FIXME make pirq table code intelligent enough to know how - // much space it's going to need. - if (new_high_table_pointer > (high_table_pointer + MAX_PIRQ_TABLE_SIZE)) { - printk(BIOS_ERR, "ERROR: Increase PIRQ size.\n"); - } - printk(BIOS_DEBUG, "PIRQ table: %ld bytes.\n", - new_high_table_pointer - high_table_pointer); - } - -#endif - -#if CONFIG_GENERATE_MP_TABLE -#define MAX_MP_TABLE_SIZE (4 * 1024) - post_code(0x9b); - - /* The smp table must be in 0-1K, 639K-640K, or 960K-1M */ - rom_table_end = write_smp_table(rom_table_end); - rom_table_end = ALIGN(rom_table_end, 1024); - - high_table_pointer = (unsigned long)cbmem_add(CBMEM_ID_MPTABLE, MAX_MP_TABLE_SIZE); - if (high_table_pointer) { - unsigned long new_high_table_pointer; - new_high_table_pointer = write_smp_table(high_table_pointer); - // FIXME make mp table code intelligent enough to know how - // much space it's going to need. - if (new_high_table_pointer > (high_table_pointer + MAX_MP_TABLE_SIZE)) { - printk(BIOS_ERR, "ERROR: Increase MP table size.\n"); - } - - printk(BIOS_DEBUG, "MP table: %ld bytes.\n", - new_high_table_pointer - high_table_pointer); - } -#endif /* CONFIG_GENERATE_MP_TABLE */ - -#if CONFIG_HAVE_ACPI_TABLES -#define MAX_ACPI_SIZE (144 * 1024) - - post_code(0x9c); - - /* Write ACPI tables to F segment and high tables area */ - - /* Ok, this is a bit hacky still, because some day we want to have this - * completely dynamic. But right now we are setting fixed sizes. - * It's probably still better than the old high_table_base code because - * now at least we know when we have an overflow in the area. - * - * We want to use 1MB - 64K for Resume backup. We use 512B for TOC and - * 512 byte for GDT, 4K for PIRQ and 4K for MP table and 8KB for the - * coreboot table. This leaves us with 47KB for all of ACPI. Let's see - * how far we get. - */ - high_table_pointer = (unsigned long)cbmem_add(CBMEM_ID_ACPI, MAX_ACPI_SIZE); - if (high_table_pointer) { - unsigned long acpi_start = high_table_pointer; - unsigned long new_high_table_pointer; - - rom_table_end = ALIGN(rom_table_end, 16); - new_high_table_pointer = write_acpi_tables(high_table_pointer); - if (new_high_table_pointer > ( high_table_pointer + MAX_ACPI_SIZE)) { - printk(BIOS_ERR, "ERROR: Increase ACPI size\n"); - } - printk(BIOS_DEBUG, "ACPI tables: %ld bytes.\n", - new_high_table_pointer - high_table_pointer); - - /* Now we need to create a low table copy of the RSDP. */ - - /* First we look for the high table RSDP */ - while (acpi_start < new_high_table_pointer) { - if (memcmp(((acpi_rsdp_t *)acpi_start)->signature, RSDP_SIG, 8) == 0) { - break; - } - acpi_start++; - } - - /* Now, if we found the RSDP, we take the RSDT and XSDT pointer - * from it in order to write the low RSDP - */ - if (acpi_start < new_high_table_pointer) { - acpi_rsdp_t *low_rsdp = (acpi_rsdp_t *)rom_table_end, - *high_rsdp = (acpi_rsdp_t *)acpi_start; - - /* Technically rsdp length varies but coreboot always - writes longest size available. */ - memcpy(low_rsdp, high_rsdp, sizeof(acpi_rsdp_t)); - } else { - printk(BIOS_ERR, "ERROR: Didn't find RSDP in high table.\n"); - } - rom_table_end = ALIGN(rom_table_end + sizeof(acpi_rsdp_t), 16); - } else { - rom_table_end = write_acpi_tables(rom_table_end); - rom_table_end = ALIGN(rom_table_end, 1024); - } - -#endif -#define MAX_SMBIOS_SIZE 2048 -#if CONFIG_GENERATE_SMBIOS_TABLES - high_table_pointer = (unsigned long)cbmem_add(CBMEM_ID_SMBIOS, MAX_SMBIOS_SIZE); - if (high_table_pointer) { - unsigned long new_high_table_pointer; - - new_high_table_pointer = smbios_write_tables(high_table_pointer); - rom_table_end = ALIGN(rom_table_end, 16); - memcpy((void *)rom_table_end, (void *)high_table_pointer, sizeof(struct smbios_entry)); - rom_table_end += sizeof(struct smbios_entry); - - if (new_high_table_pointer > ( high_table_pointer + MAX_SMBIOS_SIZE)) { - printk(BIOS_ERR, "ERROR: Increase SMBIOS size\n"); - } - printk(BIOS_DEBUG, "SMBIOS tables: %ld bytes.\n", - new_high_table_pointer - high_table_pointer); - } else { - unsigned long new_rom_table_end = smbios_write_tables(rom_table_end); - printk(BIOS_DEBUG, "SMBIOS size %ld bytes\n", new_rom_table_end - rom_table_end); - rom_table_end = ALIGN(new_rom_table_end, 16); - } -#endif - - post_code(0x9e); - -#define MAX_COREBOOT_TABLE_SIZE (32 * 1024) - post_code(0x9d); - - high_table_pointer = (unsigned long)cbmem_add(CBMEM_ID_CBTABLE, MAX_COREBOOT_TABLE_SIZE); - - if (high_table_pointer) { - unsigned long new_high_table_pointer; - - /* FIXME: The high_table_base parameter is not reference when tables are high, - * or high_table_pointer >1 MB. - */ - u64 fixme_high_tables_base = 0; - - /* Also put a forwarder entry into 0-4K */ - new_high_table_pointer = write_coreboot_table(low_table_start, low_table_end, - fixme_high_tables_base, high_table_pointer); - - if (new_high_table_pointer > (high_table_pointer + - MAX_COREBOOT_TABLE_SIZE)) - printk(BIOS_ERR, "%s: coreboot table didn't fit (%lx)\n", - __func__, new_high_table_pointer - - high_table_pointer); - - printk(BIOS_DEBUG, "coreboot table: %ld bytes.\n", - new_high_table_pointer - high_table_pointer); - } else { - /* The coreboot table must be in 0-4K or 960K-1M */ - write_coreboot_table(low_table_start, low_table_end, - rom_table_start, rom_table_end); - } - - /* Print CBMEM sections */ - cbmem_list(); -} diff --git a/src/arch/x86/boot/wakeup.S b/src/arch/x86/boot/wakeup.S deleted file mode 100644 index 38d6ea43ae..0000000000 --- a/src/arch/x86/boot/wakeup.S +++ /dev/null @@ -1,99 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2009 Rudolf Marek <r.marek@assembler.cz> - * Copyright (C) 2009 coresystems GmbH - * - * 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. - */ - -#define WAKEUP_BASE 0x600 -#define RELOCATED(x) (x - __wakeup + WAKEUP_BASE) - -/* CR0 bits */ -#define PE (1 << 0) - -#ifdef __x86_64__ - .code64 -#else - .code32 -#endif - - .globl __wakeup -__wakeup: - /* First prepare the jmp to the resume vector */ - mov 0x4(%esp), %eax /* vector */ - /* last 4 bits of linear addr are taken as offset */ - andw $0x0f, %ax - movw %ax, (__wakeup_offset) - mov 0x4(%esp), %eax - /* the rest is taken as segment */ - shr $4, %eax - movw %ax, (__wakeup_segment) - - /* Then overwrite coreboot with our backed up memory */ - cld - movl 8(%esp), %esi - movl 12(%esp), %edi - movl 16(%esp), %ecx - shrl $2, %ecx - rep movsl - - /* Activate the right segment descriptor real mode. */ - ljmp $0x28, $RELOCATED(1f) -1: -.code16 - /* 16 bit code from here on... */ - - /* Load the segment registers w/ properly configured - * segment descriptors. They will retain these - * configurations (limits, writability, etc.) once - * protected mode is turned off. - */ - mov $0x30, %ax - mov %ax, %ds - mov %ax, %es - mov %ax, %fs - mov %ax, %gs - mov %ax, %ss - - /* Turn off protection */ - movl %cr0, %eax - andl $~PE, %eax - movl %eax, %cr0 - - /* Now really going into real mode */ - ljmp $0, $RELOCATED(1f) -1: - movw $0x0, %ax - movw %ax, %ds - movw %ax, %es - movw %ax, %ss - movw %ax, %fs - movw %ax, %gs - - /* This is a FAR JMP to the OS waking vector. The C code changed - * the address to be correct. - */ - .byte 0xea - -__wakeup_offset = RELOCATED(.) - .word 0x0000 - -__wakeup_segment = RELOCATED(.) - .word 0x0000 - - .globl __wakeup_size -__wakeup_size: - .long . - __wakeup |